2010-08-04 10 views
6

Tengo una función en particular que quiero ejecutar una vez, y solo después de la finalización de varias solicitudes AJAX.Activar una función solo después de la finalización de varias solicitudes AJAX

Mi solución actual se ve un poco como esto:

function doWork() { 
    //This is the function to be run once after all the requests 
} 

//some tracking/counting variables 
var ajaxDoneCounter = 0; 
var numOfAjaxRequests = 5; 
var workDone = false; 

function doWorkTrigger() { 
    ajaxDoneCounter++; 
    if(!workDone && ajaxDoneCounter >= numOfAjaxRequests) { 
     workDone = true; 
     doWork(); 
    } 
} 

// ... 

//and a number of ajax requests (some hidden within functions, etc) 
//they look something like this: 
$.ajax({ 
    url: "http://www.example.com", 
    dataType: "json", 
    success: function(data) { 
     //load data in to variables, etc 
     doWorkTrigger(); 
    } 
}); 

Una trampa obvia en lo anterior es que cualquier llamada AJAX que no tiene éxito no aumentará ajaxDoneCount y así doWork() probablemente nunca será llamado. Puedo solucionarlo utilizando la devolución de llamada error dentro de cualquier $.ajax, por lo que no me preocupa demasiado.

Lo que quiero saber es si lo anterior es seguro y/o es una buena práctica.
¿Hay algún truco que me haya perdido, o cualquier otra cosa que pueda funcionar mejor?

+1

Es lo que le hubiera sugerido que haga al leer la descripción del problema. No estoy seguro de que "no se me ocurra nada mejor" es una "respuesta" adecuada, así que simplemente comente en su lugar. ;-) – Chris

Respuesta

6

Actualización: Dado que jQuery 1.5, deferred objects[docs] proporcionan una solución más limpia. Have a look at an example here.


me gustaría utilizar .ajaxComplete(), que se activará cada vez que una llamada Ajax completado (éxito o error):

var numOfAjaxRequests = 5; 

$(document).ajaxComplete(function() { 
    numOfAjaxRequests--; 
    if(!numOfAjaxRequests) { 
     doWork(); 

    } 
}); 

Entonces no tiene que editar cada petición Ajax.

Incluso puede utilizar .ajaxSend() para ser notificado de iniciar peticiones Ajax, en lugar de codificar (pero no estoy seguro de si esto realmente funciona, tal vez usted experimentará condiciones de carrera):

var numOfAjaxRequests = 0; 

$(document).ajaxSend(function() { 
    numOfAjaxRequests++; 
}); 
+0

Ah, es bueno saberlo, pero ¿qué pasa si tengo dos juegos de llamadas Ajax cada uno disparando una función separada (no, me pregunto). ¿Este método me permitiría separar los dos conjuntos para que ambas funciones no se queden esperando por los dos grupos que termina? – DMA57361

+0

@ DMA57361: Eche un vistazo a la documentación.El XMLHttpRequest y las opciones de la llamada Ajax se pasarán a la devolución de llamada. Es posible que pueda distinguir las llamadas con esta información. En la documentación hay un ejemplo de que la devolución de llamada solo se ejecuta si la llamada Ajax fue a una URL específica. –

+0

Me parece bien, creo que tendré una buena lectura del documento e investigaré un poco más a estos dos. Gracias. – DMA57361

0

I don' Sabe lo suficiente sobre las funciones internas de JavaScript, pero existe el peligro de que la operación:

ajaxDoneCounter++; 

no sea atómica. Si ese es el caso, entonces esto podría estar sujeto a una condición de carrera.

+0

¿Por qué el voto a favor? Si ++ es atómico en JavaScript, publique un comentario al respecto. Mi investigación rápida después de publicar la respuesta parece indicar que ECMAScript no declara si ++ es atómico o no. –

+0

Me preguntaba acerca de esto -1 también, y encontré [esto] (http://stackoverflow.com/questions/1663125/is-javascript-multithreaded) pregunta, que parece indicar que JavaScript solo se ejecuta como un solo hilo, por lo que presumiblemente solo pondrá en cola las devoluciones de llamada ajax cuando terminen, lo que significa que este problema en particular no es relevante. Aún así, habría sido útil si quienquiera que haya votado negativamente se hubiera molestado en * decirnos * que ... – DMA57361

+0

Sí, y el comentario en http://stackoverflow.com/questions/1663125/is-javascript-multithreaded/1663578#1663578 indica que puede no ser siempre así. –

1

Creo que debería utilizar complete(XMLHttpRequest, textStatus) ajax evento en lugar de éxito (datos, textStatus, XMLHttpRequest).

De acuerdo con jQuery ayuda:

complete(XMLHttpRequest, textStatus) 

Una función que se llamará cuando se ejecutan (después del éxito y devoluciones de llamada de error) los finalizar la petición. La función se pasa dos argumentos: El objeto XMLHttpRequest y una cadena que describe el estado de la solicitud. Este es un Evento Ajax.

Cuestiones relacionadas