ajax - for - jquery deferred example
Esperando respuesta(s) jQuery AJAX (5)
Esta pregunta ya tiene una respuesta aquí:
Tengo una página que, utilizando jQuery .ajax que se llama 100 veces (async: true), el problema es que, cuando se están cargando, necesito que el sistema espere a que regresen TODAS las 100 llamadas antes de continuar. ¿Cómo voy a hacer esto?
¡Gracias por adelantado! :)
Actualizar:
Estas llamadas se realizan en un bucle for () (hay 100 de ellas :))
100 llamadas ajax? Parece un requisito muy extraño y lo que estás tratando de lograr podría lograrse utilizando otro método:
var i = 0; function myCallback() { alert(''Completed 100 times''); } function doAjax() { $.ajax({ url: ''blah.php'', data: ''hello=world'', success: function(response) { i++; }, complete: function() { if(i < 100) { doAjax(); } else { myCallback(); } } }); } doAjax(); // start
Este tipo de problema surge en todas partes en el diseño SQL de la base de datos, y aunque no es exactamente el mismo, el problema es exactamente lo que le proporcionará: comunicaciones de red.
Debe cuidarse de él porque volverá a morderlo si no lo hace correctamente, es decir, los usuarios se sentirán muy molestos DEBEN esperar. No puedo enfatizar esto lo suficiente.
Aquí está el escenario: desea transferir muchos fragmentos pequeños de información de su servidor a petición. Cada solicitud depende de una serie de factores que operan de manera eficiente. Todo lo cual está fuera de tu control:
Wide area Network reposnse time (anywhere in the world right?)
Locak area Network reposnse time (anywhere in the building)
WebServer Load
WebServer Response time
Database response time
Backend Script run time
Javascript run time to process the result
The fact that the browsers are generally limited to 6-8 parallel AJAX requests at once (I think - someone correct me on the exact number)
Multiplique eso por solicitud (erm ... en su caso x 100)
¿Obtener la imagen?
Podría funcionar maravillosamente bien en una máquina local. Puede que incluso esté ejecutando su propia base de datos y servidor web en la misma máquina ... pero intente eso en la naturaleza y en poco tiempo tendrá problemas de fiabilidad.
Escuche, lo más simple que puede hacer es envolver TODOS sus parámetros en UN arreglo JS y enviarlo en UNA solicitud POST. Luego, en el servidor, haga todas las selecciones de su base de datos y enrolle las respuestas en UNA respuesta JSON / XML.
En ese momento, solo está esperando una respuesta AJAX. Puede encontrar todos sus datos en el resultado JSON / XML.
Dado que está trabajando con 100 solicitudes, probablemente pueda medir el ahorro de tiempo con un cronómetro.
Tómelo de mi parte - haga la menor cantidad posible de solicitudes de red.
No soy un tipo JS pero crearía una variable global, este sería el contador, y definiría una función cronometrada para verificar esta var globalmente periódicamente si llegaba a 100 o no.
EDITAR: setTimeout ()
Puede utilizar api de objeto diferido . Siempre que $ .ajax devuelva el objeto diferido, puede probar el siguiente código para usar loop:
var ajaxes = [];
for (i = 1; i < 100; i++) {
ajaxes[i] = $.ajax({/*data*/});
}
$.when.apply( ajaxes )
.then(function(){
console.log( ''I fire once all ajax requests have completed!'' );
})
.fail(function(){
console.log( ''I fire if one or more requests failed.'' );
});
PS Hay un gran artículo sobre el uso de objetos diferidos por Eric Hynds Uso de diferidos en jQuery 1.5
La buena manera de hacer esto es con $.when
. Puedes usar esto de la siguiente manera:
$.when(
$.ajax({/*settings*/}),
$.ajax({/*settings*/}),
$.ajax({/*settings*/}),
$.ajax({/*settings*/}),
).then(function() {
// when all AJAX requests are complete
});
Alternativamente, si tiene todas las llamadas AJAX en una matriz, puede usar apply
:
$.when.apply($, ajaxReqs);
Tenga en cuenta que esto requiere al menos jQuery 1.5.
Para agregar las solicitudes AJAX a una matriz, haga algo como esto:
var ajaxReqs = [];
for (var i = 0; i < 100; i++) {
ajaxReqs.push($.ajax({
/* AJAX settings */
});
}
$.when.apply($, ajaxReqs).then(function() {
// all requests are complete
});