2013-04-03 15 views
5

Zakładając, mam następujące:Jak wykryć zakończenie przetwarzania wielu wywołań ajax w javascript?

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

Czy jest jakiś sposób mogę pop okno ostrzeżenia po wszystkich „nie” są zakończone po trzech powtórzeń? W jaki sposób? Pomoże w tym składnia.

Odpowiedz

11

Wywołanie ajax zwraca obiekt obietnicy jQuery. Możesz zebrać dane wyjściowe każdego z nich w tablicy i użyć $.when, aby "połączyć obietnice razem".

Ten kod jest podstawową ideą, co chcesz:

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

Przeglądarka może mieć wiele otwartych połączeń HTTP, nie pozwól naysayers przekonać inaczej. Oto tabela z maksymalnymi współbieżnymi połączeniami obsługiwanymi przez przeglądarkę. Niech statystyk użytkowania witryny będzie twoim przewodnikiem, ale nawet 2 żądań AJAX na raz jest szybszy niż całkowicie synchronicznych żądań danych ...

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

Czy nie byłoby prostsze po prostu połączenia synchroniczne? – Ohgodwhy

+2

Następnie wszystkie trwają dłużej? Ten punkt w ajax jest taki, że możesz uzyskać wiele połączeń na raz. –

+0

Maksymalnie możesz mieć otwarte na raz jest 2 ... I to nie jest * punkt * ajax, po prostu jest to 'opcja'. – Ohgodwhy

0

Można użyć tablicę stanów dla tego:

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

Proszę przesunąć 'gotowy [0] = false's do pętli. – Bergi

2

Jako globalny:

var complete = 0; 

Wszystko AJAX wzywa;

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

Wykonałoby się to po wykonaniu trzech wywołań AJAX. Jeśli jednak chcesz go zwiększyć, zrób to.

+2

Odroczone obietnice i obietnice są znacznie czystszym sposobem na rozwiązanie tego problemu, zwłaszcza gdy liczba wywołań ajaxów może być zmienna, więc nie można kodować w 3 –

+0

Globals nie są potrzebne dla tego problemu. –

Powiązane problemy