2012-01-24 13 views
5

ho qualcosa di simile a questo:Come faccio a sapere quando viene eseguito l'ultimo async?

for (var i=0;i<result.qry.ROWCOUNT;i++) { 
    myAsync(i); 
} 

Come faccio a sapere quando tutte le mie funzioni asincrone hanno terminato l'esecuzione?

A rischio di qualcuno che risponde con "Richiede più jQuery!", Posso utilizzare l'oggetto promessa jQuery? O differita o qualcosa del genere?

+0

Con jQuery è possibile usare '.done()' o '.Poi()' combinata con '$ .quando()': http : //stackoverflow.com/a/5817886/1095206 – BartekR

+0

Grazie mille. Questo è qualcosa che stavo cercando! –

risposta

1

In jQuery, c'è la funzione $.ajaxStop che viene eseguita dopo che è stato eseguito l'ultimo Ajax.

7

Tenere traccia di quante chiamate asincrone sono in sospeso. Quando finisce, decrementa il tuo contatore. Quando arrivi a 0, ti trovi nell'ultima callback.

var asyncsLeft = 0; 
for (var i=0;i<10;++i){ 
    asyncsLeft++; 
    doSomethingAsyncWithCallback(function(){ 
    // This should be called when each asynchronous item is complete 
    if (--asyncsLeft==0){ 
     // This is the last one! 
    } 
    }); 
} 

A causa della natura a thread singolo di JavaScript non v'è alcuna condizione di competizione potenziale in cui si potrebbe ottenere il callback invocato prima che tutte le chiamate asincrone sono stati in coda. È possibile inserire la chiamata asyncsLeft++ dopo lo doSomethingAsynchronous, se lo si desidera.

+1

Suggerirei qualcosa di simile: usa due variabili, una che calcola il numero totale di risorse, e una che tiene traccia di quante hanno caricato/fallito (probabilmente in altre due variabili). Con una variabile, si rischia la minima possibilità che una richiesta finisca prima che il codice ne faccia una nuova, che supporrà prematuramente che tutto sia caricato (sì, questo è effettivamente successo a me). Inoltre, l'utilizzo di due variabili può mostrare lo stato di avanzamento delle risorse caricate. –

+0

@JeffreySweeney Se li metti a calci tutti in un unico ciclo, allora no, non corri quel rischio. Questo è ciò di cui parla il mio testo in corsivo. Nessun callback inizierà ad essere invocato fino a quando il ciclo 'for' non sarà terminato. – Phrogz

-2

Utilizzare una funzione di callback:

for (var i=0;i<result.qry.ROWCOUNT;i++) { 
    myAsync(i, myCallback); 
} 

function myCallback(i){ 
    //set result.qry.ROWCOUNT to a var somewhere above if it's not available in this scope 
    if(i == (result.qry.ROWCOUNT - 1)){ 
    //now you know you're actually done with all requests 
    } 
} 
function myAsync(i,callback){ 
    ///do work 
    callback(i); 
} 
+1

Funziona solo se le attività asincrone terminano nell'ordine in cui sono state avviate. –

+0

In questo caso, 'myAsync' è sincrono, è necessario passare la richiamata a qualsiasi metodo/libreria asincrona che si sta utilizzando. –

+0

punto eccellente –

1

Se si utilizza jQuery, è possibile anche utilizzare i ajaxSend e ajaxComplete metodi per mantenere il vostro codice contatore separato dal codice di spedizione.

var ajaxPending = 0; 

function ajax_changed(indicator, pending) { 
    if (pending) 
     $(indicator).show(); 
    else 
     $(indicator).hide(); 
} 

$('#loading-indicator').ajaxSend(function() { 
    ajax_changed(this, ++ajaxPending); 
}); 

$('#loading-indicator').ajaxComplete(function() { 
    ajax_changed(this, --ajaxPending); 
}); 
2

Ecco come lo farei:

//Do stuff up here to get records 
var rowCount = result.qry.ROWCOUNT, //Save the row count 
    asyncCount = 0, //The count of complete async calls 
    asyncCallback = function() { 
     //To be called whenever an async operation finishes 
     asyncCount++; //Increment the row counter 
     if (asyncCount >= rowCount) { 
      //Do stuff when they're all finished 
     } 
    }; 

for (var i=0;i<rowCount;i++) { 
    myAsync(i, asyncCallback); 
} 

function myAsync(index, completeCallback) { 
    //Do async stuff with index 
    //Call completeCallback when async stuff has finished or pass it 
    // into the async function to be called 
} 
Problemi correlati