6

我无法在延迟对象的回调之前执行每个 ajax 请求的完成/失败/始终回调。

我遇到的问题是我的一些 ajax 请求可能会失败,但是无论一个失败还是没有一个失败,我都需要执行相同的代码。

很难准确解释,所以我做了这个小提琴来帮助说明我遇到的问题。 http://jsfiddle.net/zZsxV/

var a1 = $.Deferred();
var a2 = $.Deferred();
var a3 = $.Deferred();

a1.done(function() {
    $('body').append('a1 done<br />');     
}).fail(function() {
    $('body').append('a1 fail<br />');     
}).always(function() {
    $('body').append('a1 always<br />');     
});

a2.done(function() {
    $('body').append('a2 done<br />');     
}).fail(function() {
    $('body').append('a2 fail<br />');     
}).always(function() {
    $('body').append('a2 always<br />');     
});

a3.done(function() {
    $('body').append('a3 done<br />');     
}).fail(function() {
    $('body').append('a3 fail<br />');     
}).always(function() {
    $('body').append('a3 always<br />');     
});

var def = $.when(a1, a2, a3);
def.always(function() {
    $('body').append('defer always <-- should be after all<br />'); 
});

setTimeout(function() {
    a1.resolve();
}, 5000);
setTimeout(function() {
    a2.reject();
}, 1000);
setTimeout(function() {
    a3.resolve();
}, 3000);

我阅读了很多关于这个主题的答案,但我不相信任何完全符合我的需要。

任何需要帮助的信息,请告诉我,我会在回来后添加。提前致谢。


编辑

我明白发生了什么。我只知道如何避免这个问题。我也尝试使用 .then 并获得相同的结果。一旦一个请求被拒绝,它会在等待其他回调之前触发失败回调。

4

3 回答 3

2

根据jQuery 文档,当 所有参数都已解析或其中一个参数被拒绝$.when时会触发回调。那么如何使用类似的东西而不是:$.when

var custom_when = function() {
    var args = $.makeArray(arguments);
    var callback = args.pop();
    var all = [];
    $.each(args, function(index, def) {
        def.always(function() {
            var idx = all.indexOf(def);
            if (idx !== -1) {
                all.splice(idx, 1);
            }
            if (!all.length) {
                callback();
            }
        });
        all.push(def);
    });
};

你可以这样使用它:

custom_when(a1, a2, a3, function() {
    // do some stuff.
});

jsFiddle 演示

于 2013-05-27T21:09:09.320 回答
1

我知道您在这里尝试做什么,但是没有方便的方法。这有效:

JSFIDDLE

$.when(a1).done(a2).done(a3).then(function() {
    $('body').append('defer always <-- should be after all<br />'); 
});

其他选择是编写自己的简单函数。查看更新的 FIDDLE

whenAllResolved(a1, a2, a3).done(function () {
    $('body').append('defer always <-- should be after all<br />');
});


function whenAllResolved(){
    var d = $.Deferred(),
        args = arguments,
        verifyDeferreds = function(){
            var allResolved = true;
            $.each(args, function(i, arg){
                if(arg.state() === 'pending'){
                    allResolved = false;
                    return false;
                }
            });
            if (allResolved){
                d.resolve();
            }
        };

    $.each(arguments, function(i, arg){
        arg.always(verifyDeferreds);
    });

    verifyDeferreds();

    return d;
}
于 2013-05-27T21:20:27.043 回答
0

嘿,我遇到了类似的问题,我没有代码,但我会尝试找到它。

无论如何,我所做的是有一个变量,其中包含我需要等待的对象数量,当其中一个完成时将其减少,然后检查它是否为 0,如果它是我可以调用另一个函数。

于 2013-05-27T20:50:47.603 回答