5

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

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

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

def 完成
def 然后
第二个 ajax 预过滤器 然后
第二个 ajax 完成
第二个 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 调用中的预过滤器函数
done 称为函数
2nd ajax prefilter then
2nd ajax done
2nd ajax then

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

4

3 回答 3

3

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

我不明白为什么先执行预过滤步骤。我原以为它会最后执行,或者根本不执行。

回调按照它们添加到延迟对象的顺序执行。并且预过滤器在 内部执行$.ajax,即甚至在$.ajax调用返回之前附加回调并且可以附加您的done和处理程序。then

于 2013-04-09T18:38:33.780 回答
1

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

于 2013-04-09T17:27:07.337 回答
1

我不明白为什么先执行预过滤步骤。我原以为它会最后执行,或者根本不执行。

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

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

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

于 2013-04-09T17:42:34.367 回答