2013-04-03 69 views
5

假设我有以下几点:如何检测何时在JavaScript中处理完多个Ajax调用?

function main() { 

    var finished = false; 

    for(var i=0; i < 3; i++) { 
    do(i); 
    } 
} 

function do(i) { 
    $.ajax({ 
    url:"myurl.com/"+i, 
    datatype:"text/xml", 
    success: function() { 

     // Two more layers of multiple nested $.ajax elements here 
    } 
    }) 
} 

是否有某种方式,所有的“做”的三个迭代后结束后,我会弹出一个警告框?怎么样?语法会有所帮助。

回答

11

ajax调用返回一个jQuery Promise对象。您可以收集数组中的每一个输出,并使用$.when将承诺“捆绑”在一起。

这段代码的背后是你想要的基本思想是:

function main() { 

    var finished = false; 

    var defs = []; 

    for(var i=0; i < 3; i++) { 
    defs.push(do(i)); 
    } 

    $.when.apply(null, defs).done(function() { 
    //this code will only run when all ajax calls are complete 
    }); 
} 

function do(i) { 
    var promise = $.ajax({ 
    url:"myurl.com/"+i, 
    datatype:"text/xml", 
    success: function() { 

     // Two more layers of multiple nested $.ajax elements here 
    } 
    }) 

    return promise; 
} 

浏览器可以有很多开放的HTTP连接,不要让反对者说服你,否则。这是一个浏览器支持的最大并发连接表。让您的站点使用统计数据成为您的指南,但即使是2个Ajax请求也会比全部同步数据请求更快...

Firefox 2: 2 
Firefox 3+: 6 
Opera 9.26: 4 
Opera 12: 6 
Safari 3: 4 
Safari 5: 6 
IE 7:  2 
IE 8:  6 
IE 10:  8 
Chrome:  6 
+0

只是使它变得更简单调用同步? – Ohgodwhy 2013-04-03 22:09:54

+2

那么他们都需要更长的时间?阿贾克斯的这一点是,你可以得到很多电话一次发生。 – 2013-04-03 22:10:33

+0

你可以一次打开的最大值是2 ...这不是ajax的*点*,它恰好是一个“选项”。 – Ohgodwhy 2013-04-03 22:11:34

0

您可以使用状态对这样的数组:

function main() { 
    var ready = new Array(3); 
    for (var i = 0; i < 3; i++) { 
    ready[i] = false; 
    } 

    for (var i = 0; i < 3; i++) { 
    do(i, ready); 
    } 
} 

function do(i, ready) { 
    $.ajax({ 
    url:"myurl.com/"+i, 
    datatype:"text/xml", 
    success: function() { 
    // If there are multiple layers then the next statements should be executed in the last layer. 
    ready[i] = true; 
    if (isAllReady(ready)) { 
     alert("All done!"); 
    } 
    } 
    }) 
} 

function isAllReady(ready) { 
    var allReady = true; 
    for (var i = 0; i < 3; i++) { 
    if (!ready[i]) { 
     allReady = false; 
    } 
    } 
    return allReady; 
} 
+0

请将'ready [0] = false'移入循环中。 – Bergi 2013-04-03 22:22:17

2

随着全球:

var complete = 0; 

所有AJAX调用;

$.ajax({ 
    ... //other attributes, 
    complete: function(){ 
    complete++; 
    if (complete == 3) { 
     alert('all completed'); 
    } 
    } 
}); 

这将在三个AJAX调用完成时执行。但是,如果您需要增加它,那就这样做。

+2

延迟和承诺是一个更简洁的方法来解决这个问题,尤其是当ajax调用的数量可能变化,所以你不能硬编码在3 – 2013-04-03 22:09:32

+0

全局不需要这个问题 – 2013-04-03 22:17:56