将一个Deferreds数组传递给$ .when()

下面是一个人为的例子:http://jsfiddle.net/adamjford/YNGcm/20/

HTML:

<a href="#">Click me!</a>
<div></div>

JavaScript的:

function getSomeDeferredStuff() {
    var deferreds = [];

    var i = 1;
    for (i = 1; i <= 10; i++) {
        var count = i;

        deferreds.push(
        $.post('/echo/html/', {
            html: "<p>Task #" + count + " complete.",
            delay: count
        }).success(function(data) {
            $("div").append(data);
        }));
    }

    return deferreds;
}

$(function() {
    $("a").click(function() {
        var deferreds = getSomeDeferredStuff();

        $.when(deferreds).done(function() {
            $("div").append("<p>All done!</p>");
        });
    });
});

我想要“全部完成!” 在所有延迟任务完成后出现,但$.when()似乎不知道如何处理Deferred对象数组。 “全做完了!” 首先发生,因为该数组不是Deferred对象,所以jQuery继续前进,并假定它刚刚完成。

我知道可以将对象传递给像$.when(deferred1, deferred2, ..., deferredX)这样的函数$.when(deferred1, deferred2, ..., deferredX)但是我不知道在我试图解决的实际问题中会有多少Deferred对象在执行。


要传递一个值的数组到任何通常希望它们是单独参数的Function.prototype.apply ,请使用Function.prototype.apply ,所以在这种情况下,您需要:

$.when.apply($, my_array).then( ___ );

见http://jsfiddle.net/YNGcm/21/

在ES6中,您可以使用... spread运算符代替:

$.when(...my_array).then( ___ );

无论哪种情况,由于您不太可能事先知道.then处理程序需要的正式参数数量,该处理程序需要处理arguments数组以便检索每个承诺的结果。


上面的解决方法(谢谢!)没有正确地解决回收提供给deferred的resolve()方法的对象的问题,因为jQuery使用单个参数调用done()fail()回调,而不是数组。 这意味着我们必须使用arguments pseudo-array来获取由延迟数组返回的所有解析/拒绝对象,这很丑陋:

$.when.apply($,deferreds).then(function() {
     var objects=arguments; // The array of resolved objects as a pseudo-array
     ...
};

因为我们传递了一个延迟数组,所以返回一个结果数组会很好。 取回实际的数组而不是伪数组也很好,所以我们可以使用像Array.sort()这样的方法。

这个解决方案受到了when.js的解决这些问题的when.all()方法的启发:

// Put somewhere in your scripting environment
if (typeof jQuery.when.all === 'undefined') {
    jQuery.when.all = function (deferreds) {
        return $.Deferred(function (def) {
            $.when.apply(jQuery, deferreds).then(
                function () {
                    def.resolveWith(this, [Array.prototype.slice.call(arguments)]);
                },
                function () {
                    def.rejectWith(this, [Array.prototype.slice.call(arguments)]);
                });
        });
    }
}

现在,您可以简单地传递一个延迟/承诺数组,并在回调中获取已解析/已拒绝的对象数组,如下所示:

$.when.all(deferreds).then(function(objects) {
    console.log("Resolved objects:", objects);
});

您可以将when方法应用到您的数组中:

var arr = [ /* Deferred objects */ ];

$.when.apply($, arr);

你如何使用jQuery Deferreds的数组?

链接地址: http://www.djcxy.com/p/9429.html

上一篇: Pass in an array of Deferreds to $.when()

下一篇: .then() vs .done()