繁体   English   中英

为什么使用$ .deferred和$ .ajax时jQuery.then()的行为不同

[英]Why does jQuery.then() behave differently when using $.deferred and $.ajax

我一直试图绕过jQuery Deferred对象。 我的目的是检查每个ajax响应(成功/失败)。 我想做到这一点而不会干扰其他声明典型$ .ajax()。done()。fail()请求的代码。

我已经使用$ .ajaxPrefilter()来获取每个ajax请求,然后再执行它。 使用jqXHR对象上的.then()方法,我设法添加了一个函数,该函数将在放置在原始$ .ajax()调用上的.done()方法之前被调用。

下面的代码将打印出以下内容:

def完成
然后定义
然后第二个ajax预过滤器
第二个ajax完成
然后第二个ajax
阿贾克斯完成
然后阿贾克斯

我不明白的是为什么要先执行预过滤器步骤。 我希望它最后执行一次,或者根本不执行。

这是我想要的行为,但是我不明白为什么。

// this is a typical usage of deferred with two done functions added, the second via .then()
var def = $.Deferred();
def.done(function(){
    document.write("def done<br>");
});
def.then(function(){
    document.write("def then<br>");
});
def.resolve();

// this is a typical ajax request with a done function added, followed by another using .then()
$.ajax("/echo/json/").done(function(){
    document.write("ajax done<br>");
}).then(function(){
    document.write("ajax then<br>");
});

// for the third request i intercept and call the .then() method 
$.ajaxPrefilter( 
    function( options, originalOptions, jqXHR ) {
                jqXHR.then(function(data, textStatus, jqXHR){
                     document.write("2nd ajax prefilter then<br>");
                    });
            });

// create a typical ajax request. these will be executed after the prefilter .then()
$.ajax("/echo/json/").done(function(){
    document.write("2nd ajax done<br>");
}).then(function(){
    document.write("2nd ajax then<br>");
});

预先感谢您的任何帮助

更新:------------

在@Bergi响应中,以下代码演示了如何在done()之前调用$ .ajaxPrefilter()。

$.ajaxPrefilter( 
    function( options, originalOptions, jqXHR ) {
            document.write("prefilter function within $.ajax call<br>");
                jqXHR.then(function(data, textStatus, jqXHR){
                     document.write("2nd ajax prefilter then<br>");
                    });
            });

var functionToRunWhenDoneIsCalled = function() {
    document.write("done is called function<br>");
    return function(){
       document.write("2nd ajax done<br>");
    }
}

$.ajax("/echo/json/").done(
    (functionToRunWhenDoneIsCalled)()
).then(function(){
    document.write("2nd ajax then<br>");
});

输出:

$ .ajax调用中的预过滤器功能
完成称为功能
然后第二个ajax预过滤器
第二个ajax完成
然后第二个ajax

这回答了我关于.then()方法如何在.done()方法之前附加到延迟的jqXHR对象的问题。

在你的情况下,与添加回调之间没有区别.done()或用.then() 仅使用.done()就足够了。

我不明白的是为什么要先执行预过滤器步骤。 我希望它最后执行一次,或者根本不执行。

回调将按添加到延迟对象中的顺序执行。 并且prefilter在$.ajax内部执行,即,甚至在$.ajax调用返回之前,也可以附加回调, then可以附加您的done和handler。

如果您不返回延迟的对象,则所有.then要做的就是向该延迟的对象添加另一个完成的失败和/或进度处理程序。 考虑到这一点,在预过滤器中添加$.ajax()$.ajax()之后添加的$.ajax()之前执行是完全有意义的.then因为pre-filter回调中的代码首先发生。 回调先入先出。

我不明白的是为什么要先执行预过滤器步骤。 我希望它最后执行一次,或者根本不执行。

您已经将另一个“要做的事情”附加到了与ajax请求关联的jqXHR上。 由于它是一个过滤器,因此会在ajax请求使用的标准完成/失败之前被附加。 处理程序按其连接的顺序运行,因此预过滤器是第一个。

请注意,由于预过滤器仅在.then()方法中附加了单个功能,因此.then()如果由于某种原因请求失败,将不会运行任何内容。 听起来您也想拥有第二个(故障处理程序)arg。

至于两个不同的ajax请求的完成顺序,这是不可预测的。 这将取决于哪个先返回。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM