3

最近我问我如何触发可变数量的 jqueryget()请求,我收到了这个代码作为一个非常有效的工作解决方案:

var d = new $.Deferred();
var promise = d.promise();
var results = [];
for (var i = 0; i < 5; i++) {
    (function(i) {
        promise = promise.then(function() {
            return $.ajax('/echo/json/', {
                data: {
                    json: JSON.stringify({foo: i})
                }
            }).done(function(data) {
                results[i] = data;
            });
        });
    }(i));
}

promise.done(function() {
    console.log(results);
});

d.resolve(); 

小提琴

我正在寻找一个解释,说明这与done()附加到 each 的多个 spromise.then()以及最后done()附加到 promise 本身的情况到底是如何工作的。是不是一个承诺(据我所知是一种特殊类型的 deferred 本身)可以完成,那么 deferred 本身也可以完成?如果它不在循环中,那么对于连续三个 ajax 请求,这种语法会是什么样子?只是想绕开它。谢谢!

4

2 回答 2

7

如果你有一个延迟对象数组,你实际上可以使用whenapply获取承诺来处理它们,然后$.done()在它们上使用:

$.when.apply($, deferredArray).done(function() {
   for (var i = 0; i < arguments.length; i++) {
      //arguments[i] is the return of the singular done() statement    
   }
});

当您不知道您正在使用多少延迟对象时,这非常有效。

于 2013-02-21T21:52:57.497 回答
3

promise 是 deferred 的包装器,它隐藏了resolvereject方法,是 deferred 的公共接口的一种。因为then()done()如果你在延迟或承诺上使用它们并没有什么区别。从现在开始,我将使用延迟一词来表示两者。

话虽如此,done()返回允许链接的延迟本身。您可以像这样添加尽可能多的完成(和失败)处理程序。他们将被一一召唤。

then()返回一个的deferred*,它可以有自己的完成和失败处理程序。

请注意,在您的代码中,您promise在每次循环迭代时替换变量中的 deferred ,因此 finaldone()不会在原始 deferred 上调用,而是在最新的上调用,由 last 返回then()

链接在一行中的所有调用看起来像这样(每个都then()返回一个新的承诺。我标记了,在其done()上调用了方法):

d.then().done().then().done().then().done().then().done().done();
         ^^^^^^        ^^^^^^        ^^^^^^        ^^^^^^^^^^^^^
        promise 1     promise 2     promise 3       promise 4

*) 实际上是它的承诺

于 2013-02-21T21:15:53.810 回答