且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用jquery deferreds处理可变数量的ajax请求

更新时间:2023-12-04 22:58:58

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

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封闭-简单的实际示例. /p>


没有干净的解决方案来获取结果.我认为您***的办法是将结果添加到数组中,并在.done回调中访问该数组.即:

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`
});

when I have a variable number of ajax requests, how can I call them using deferreds?

my guess:

//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++;
        }

    });
}

If you want to execute the Ajax calls sequentially, you have to return the promise from the callback and also attach a new callback to the last promise object:

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();

As of jQuery 1.8, you should use .then instead of .pipe.

Another problems is (in your example at least) that at the time the callbacks are executed, i won't have the value you expect. You can use an immediately invoked function expression to capture the current value of i. See JavaScript closure inside loops – simple practical example for more info.


There is no clean solution for getting the results. I think the best you could do is adding the results to an array and access that array in the .done callback. I.e.:

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`
});