2

当我有可变数量的 ajax 请求时,如何使用延迟调用它们?

我猜:

//qty_of_gets = 3;

function getHTML(productID, qty_of_gets){

    var dfd = $.Deferred(),
            i = 0,
            c = 0;

    //this is where there could be some magic to 
    //do multiple ajax posts
    //obviously I'm out of my depth here...
    while (i <= qty_of_gets){

        dfd.pipe(function(){
            $.get("queries/html/" + product_id + i + ".php");
        });                       
    i++
    }
    dfd.done(function(){

        while (c <= qty_of_gets){
           $('myDiv').append(c);
           c++;
        }

    });
}
4

2 回答 2

6

如果要按顺序执行 Ajax 调用,则必须从回调中返回承诺,并将新的回调附加到最后一个承诺对象:

var dfd = $.Deferred(),
   promise = dfd.promise(),
   i = 0,
   c = 0;

while (i <= qty_of_gets) {
    // needs an IIFE
    (function(i)
        promise = promise.then(function(){
            return $.get("queries/html/" + product_id + i + ".php");
        });
    }(i++));                       

}

promise.done(function(){

    while (c <= qty_of_gets){
       $('myDiv').append(c);
       c++;
    }

});

// resolve deferred
dfd.resolve();

从 jQuery 1.8 开始,您应该.then使用.pipe.

另一个问题是(至少在您的示例中),在执行回调时,i不会具有您期望的值。您可以使用立即调用的函数表达式来捕获i. 请参阅循环内的 JavaScript 闭包——了解更多信息的简单实用示例


没有获得结果的干净解决方案。我认为您能做的最好的事情就是将结果添加到一个数组并在.done回调中访问该数组。IE:

var results = [];

while (i <= qty_of_gets) {
    // needs an IIFE
    (function(i)
        promise = promise.then(function(){
            return $.get("queries/html/" + product_id + i + ".php")
                     .then(function(result) {
                       results[i] = result;
                     });
        });
    }(i++));                       

}

promise.done(function(){
    // do something with `results`
});
于 2013-02-20T21:15:19.450 回答
3

.pipe关闭,您需要从回调中返回一个 Promise 对象。
请参阅 felix 的回答,下一个示例除了缺少返回之外还有其他问题。

dfd.pipe(function(){
    return $.get("queries/html/" + product_id + i + ".php");
});  

另外,我认为它实际上还没有写在任何地方,但是 .pipe在最近的版本中是这样在核心中实现的:

promise.pipe = promise.then

因此,您应该替换dfd.pipedfd.then
参考:http ://api.jquery.com/deferred.pipe/

提到的 adeneo 的替代方法是使用$.when

function getHTML(productID, qty_of_gets) {

    var dfdArr = [];

    while (i <= qty_of_gets) {
        dfdArr.push($.get("queries/html/" + product_id + i + ".php"));
        i++
    }
    $.when.apply(null, dfdArr).done(function () {

        for (response in arguments) {
            $('#myDiv').append(response[0]);
        }

    });
}
于 2013-02-20T20:52:02.853 回答