2011-04-24 56 views
5

Estoy intentando llevar a cabo la siguiente secuencia de operaciones usando jQuery en HTML.realizar muchas peticiones AJAX en paralelo, y ejecutar una función de todos ellos completa

  • una lista de URL se construye
  • Cada una de estas URL se solicita el uso de $ .getJSON (url) en paralelo
  • esperar a que todas las solicitudes para completar o fallen (404 podría suceder)
  • Tome los datos de todas las Solicitudes JSON completas y haga algo.

que construye el código Java-Script publicado a continuación. Funciona perfecly salvo que una de las peticiones falla debido a un error 404: Entonces, $.when no se ejecuta porque al instante aborta si falla un peticiones. ¿Puedes de alguna manera anular las solicitudes de Ajax, para que no fallen pero en cambio devuelvan una fuente vacía?

Ya leí this y this publicación, pero no proporciona una solución donde se puede ejecutar el código después de que se hayan completado todas las consultas.

function fetchData() { 
    queries = []; 
    //urls is initialized somewhere else containing all urls 
    for(var url in urls) { 
     queries.push($.getJSON(url)); 
    } 

    $.when.apply(this, queries).done(function() { 
     console.log("Finished all queries, got "+arguments.length+" results"); 
     //Now arguments is a array containing the results of all requests 
    } 

    //function returns instantly, no problem! 
} 
+0

No soy tan experimentado en jQuery, pero parece que necesita contador de consulta. Es decir. Establezca un contador para la cantidad de consultas que enviará. En la función de éxito, o error correspondiente, decrementa el contador (¿es un decremento unitario atómico en Javascript?). Una vez que el contador llega a cero, usted sabe que todas las solicitudes están hechas y puede procesar los resultados.Por supuesto, tendrá que almacenar en caché los resultados de las consultas para su posterior procesamiento una vez que todas las consultas estén completas. – ewh

+0

Duplicado: http://stackoverflow.com/questions/1060539/parallel-asynchronous-ajax-requests-using-jquery – joeytwiddle

Respuesta

2

yo podría hacer algo como esto:

$(document).ready(function(){ 
    var _q = ['/echo/json/', '/echo/json/', 'mybadurl']; 
    var _d = []; 
    for(u in _q) 
    { 
     $.ajax({ 
      url: _q[u], 
      success: function(data){ 
       pushData(data); 
      }, 
      error: function(x){ 
       pushData(x); 
      } 
     }); 
    } 

    function pushData(d) 
    { 
     _d.push(d); 
     if(_d.length == _q.length) 
     { 
      alert('were done'); 
     } 
    } 
}); 

Aquí, usted está empujando los datos, ya sea del éxito o de error en la matriz _d y pruebas para asegurarse de haber recibido todas las respuestas antes de continuar (alert('were done');).

Por supuesto, usted podría hacer que este inteligente empujando un objeto que contiene el estado op junto con la carga útil en _d, pero esto fue un truco rápido juntos para demostrar cómo iba a ir más probable de hacer lo que estás pidiendo .

Fiddle here

1

Algo como esto:

function fetchData() { 
    queries = []; 
    //urls is initialized somewhere else containing all urls 
    for(var url in urls) { 
     queries.push($.getJSON(url)); 
    } 

    var returned = 0; 
    for (var i = 0; i < queries.length; i += 1) { 
     call_ajax_somehow(queries[i], function() { 
      console.log("callback called"); 
      returned += 1; 
      if (returned === queries.length) { 
       console.log("Got all " + queries.length + " of them"); 
      } 
     }); 
    } 
} 

que tendría que comprobar la especificación Ajax jQuery sobre la forma de llamarlo exactamente y cómo manejar los errores (es decir, la forma de especificar la respuesta de error) pero no debería ser demasiado difícil modificar el código.

1

Algo como esto debería funcionar:

function fetchData() { 
    var queriesRun = 0; 
    var allData = []; 

    var urls = ["http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com", 
       "http://stackoverflow.com/thisdoesnotexist"]; 

    var totalQueries = urls.length; 

    var complete = function(jqXHR, textStatus) { 
     queriesRun++; 
     console.log(queriesRun); 

     if(queriesRun == totalQueries) { 
      console.log("all done"); 
      console.log(allData); 
     } 
    }; 

    for(var i = 0; i < urls.length; i++) { 
     var url = urls[i]; 
     jQuery.ajax({ 
      url: url,   
      success: function(data, textStatus, jqXHR) { 
       allData.push(data); 
      }, 
      complete: complete 
     }); 
    } 
} 

Desde el manejador de complete se ejecuta después de que el controlador de error y success, queriesRun obtendrá incrementa cada vez que la llamada AJAX completa. Este controlador también verifica si el número de consultas ejecutadas es igual al número total de consultas. Si lo es, funcionará con los datos.

He añadido console.log s en el código para que pueda ver fácilmente lo que está pasando (sólo ejecutarlo en Firebug).

Cuestiones relacionadas