2011-06-06 24 views
18

Tengo una página que, usando jQuery .ajax que se llama 100 veces (async: true), el problema es que cuando se cargan todas, necesito que el sistema espere a que TODAS las 100 llamadas regresen antes de continuar. ¿Cómo voy a hacer esto?Esperando respuesta (s) de jQuery AJAX

¡Gracias de antemano! :)

Actualización:

Estas llamadas se realizan en un bucle for() (hay 100 de ellos :))

+1

¿Son estas llamadas separadas ajax() o una donde se cambia la URL de solicitud? –

+2

Creo que la misma solución de http://stackoverflow.com/questions/6239333/preventing-submit-until-ajaxes-are-done podría funcionar para usted. – Niklas

+0

Matthew Riches: Varios. Niklas: Gracias :) ¡Lo investigaré! – Eax

Respuesta

37

La buena manera de hacerlo es con $.when. Usted puede utilizar esto como sigue:

$.when(
    $.ajax({/*settings*/}), 
    $.ajax({/*settings*/}), 
    $.ajax({/*settings*/}), 
    $.ajax({/*settings*/}), 
).then(function() { 
    // when all AJAX requests are complete 
}); 

Alternativamente, si usted tiene toda la llamadas AJAX en una matriz, se puede usar apply:

$.when.apply($, ajaxReqs); 

Tenga en cuenta que esto requiere al menos jQuery 1.5.


Para añadir las peticiones AJAX a una matriz, hacer 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 
}); 
+0

tengo que amar a jquery :) – melaos

+2

Aaargh ... justo cuando crees que has empezado jQuery, hay algo nuevo. –

+0

Tengo todas las llamadas Ajax en un bucle for, ¿cómo las 'agrego' a una matriz, entonces? :) – Eax

0

Yo no soy un tipo JS, pero me gustaría crear una variable global, esta Sería el contador, y definiría una función cronometrada para verificar esta var global periódicamente si llegara a 100 o no.

EDIT: setTimeout()

+0

¿Qué quiere decir con una función sincronizada? :) – Eax

+2

Olvídalo, como veo, obtendrás mejores soluciones – Damien

3

Puede utilizar Deferred object api. Mientras $ .ajax vuelve diferidas objeto puede probar el siguiente código para utilizar en bucle:

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.'); 
    }); 

P. S. Hay un excelente artículo sobre el uso de objetos diferidos por Eric Hynds Using Deferreds in jQuery 1.5

+0

Actualicé la pregunta principal, ¿aún puedo utilizar su camino si estoy haciendo todas las llamadas Ajax en un bucle for? – Eax

+0

Actualicé mi respuesta. –

+1

Esto no funcionará. Si pasa algo que no sea un objeto diferido a '$ .when' (incluida una matriz que contiene objetos diferidos), se devolverá de inmediato. Necesitas usar '$ .when.apply' como en mi respuesta para evitar esto. – lonesomeday

2

100 llamadas Ajax? Parece un requisito muy extraño y lo que estamos tratando de lograr muy posiblemente podría lograrse con cualquier 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 
+0

Sé que es bastante extraño :) Probablemente debería agregar que cada llamada es diferente, y que necesito todos los datos de retorno ... – Eax

+0

¿De qué manera cada llamada es diferente? Diferentes URL finales? Datos diferentes? Es bastante fácil manipular mi respuesta para permitir eso y almacenar los datos devueltos en otra variable, que se envía a la función de devolución de llamada. – amustill

+0

Datos diferentes :) Pero supongo que se trata de lo mismo, solo necesito cambiar los datos. – Eax

4

Este tipo de problema surge por todas partes en el diseño de bases de datos SQL - y aunque no es exactamente la misma - la el problema es exactamente lo que le conseguirá: comunicaciones de red.

Tienes que tener cuidado porque volverá a morderte si no lo haces correctamente, es decir, los usuarios se sentirán muy molestos TENIENDO QUE esperar. No puedo enfatizar esto lo suficiente.

Aquí está el escenario: Desea transferir muchos pequeños fragmentos de información de su servidor a petición. Cada solicitud depende de una serie de factores que operan de manera eficiente. Todos los cuales están fuera de su 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) 

que se multiplican por petición (erm ... en su caso x 100)

Obtener la foto?

Podría funcionar maravillosamente bien en la prueba en una máquina local. Incluso podría estar ejecutando su propio db y servidor web en la misma máquina exacta ...pero intente eso en la naturaleza y en poco tiempo considerará la falta de fiabilidad como un problema.

Escucha, lo más simple es concluir TODOS los parámetros en UNA matriz JS y enviarlos en UNA SOLICITUD POST. Luego, en el servidor, toda su base de datos selecciona y acumula las respuestas en UNA RESPUESTA DE JSON/XML.

En ese momento, solo está esperando una respuesta de AJAX. Puede encontrar todos sus datos en el resultado JSON/XML.

Dado que está trabajando con 100 solicitudes, ¡probablemente pueda realmente medir el ahorro de tiempo con un cronómetro!

Tómelo de mi parte: haga la menor cantidad posible de solicitudes de red.

+1

Muchas gracias por una respuesta extremadamente elaborada :) Sin embargo, (siempre hay uno de estos, ¿no?), Lo que estoy AJAX no es en realidad una base de datos, sino una página que raspa un sitio web específico para obtener información. Así que realmente no puedo hacer todas esas 100 solicitudes a la vez, o mejor dicho, puedo hacerlo, pero eso requiere HORAS (hice la prueba del cronómetro;)) Mientras que cuando se ejecuta con jQuery + Ajax toma minutos :) ¡Gracias de nuevo! – Eax

+0

No estoy seguro de cómo logró obtener una página web protegida en * horas *? He hecho lo mismo con CURL para adquirir metadatos de páginas anteriores. Solo puede tomar el tiempo que lleva servir la página, por lo que debe haber estado haciendo algo muy incorrecto. – T9b

Cuestiones relacionadas