2012-01-24 26 views
5

tengo algo como esto:¿Cómo puedo saber cuándo se realizó la última sincronización?

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

¿Cómo sé cuando todas mis funciones asíncronas han terminado de ejecutarse?

A riesgo de que alguien responda con "¡Necesita más jQuery!", ¿Puedo usar el objeto de promesa jQuery? ¿O diferido o algo así?

+0

Con jQuery se puede usar '.done()' 'o .then()' 'combinado con $ .cuando()': http : //stackoverflow.com/a/5817886/1095206 – BartekR

+0

Muchas gracias. ¡Eso es algo que estaba buscando! –

Respuesta

1

En jQuery, existe la función $.ajaxStop que se ejecuta después de que se ejecutó el último Ajax.

7

Mantenga un registro de cuántas llamadas asincrónicas están pendientes. Cuando termine cada uno, disminuya su contador. Cuando llegas a 0, estás en la última devolución de llamada.

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

Debido a la naturaleza de un único subproceso de JavaScript no existe una posible condición de carrera en la que podría obtener su devolución de llamada se invoca antes de que todas las llamadas asíncronas se han hecho cola. Es seguro poner la llamada asyncsLeft++ después del doSomethingAsynchronous, si lo desea.

+1

Sugeriría algo similar: use dos variables, una que traduzca la cantidad total de recursos, y otra que rastree cuántos han cargado/fallado (posiblemente en otras dos variables). Con una variable, corre el riesgo de que exista una pequeña posibilidad de que una solicitud finalice antes de que el código haga una nueva, lo que prematuramente asumirá que todo está cargado (sí, esto realmente me ha sucedido a mí). Además, el uso de dos variables puede mostrar el progreso de los recursos cargados. –

+0

@JeffreySweeney Si los patea en un solo ciclo, entonces no, no corre ese riesgo. De eso se trata mi texto en cursiva. No se invocarán devoluciones de llamada hasta después de que su bucle 'for' haya finalizado. – Phrogz

-2

utilizar una función de devolución de llamada:

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

Esto solo funciona si las tareas asincrónicas finalizan en el orden en que se inician. –

+0

En este caso, 'myAsync' es sincrónico, debe pasar la devolución de llamada a los métodos/biblioteca asíncrona que esté utilizando. –

+0

punto excelente –

1

Si está utilizando jQuery, también se pueden utilizar los métodos ajaxSend y ajaxComplete para mantener su código del contador separado de su código de envío.

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

Esta es la forma en que lo haría:

//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 
} 
Cuestiones relacionadas