¿Alguna forma mejor de combinar varias devoluciones de llamada?
Frecuentes
Visto 6,241 veces
4
Necesito llamar a una función asíncrona (con bucle) para múltiples valores y esperar esos resultados. Ahora mismo estoy usando el siguiente código:
(function(){
var when_done = function(r){ alert("Completed. Sum of lengths is: [" + r + "]"); }; // call when ready
var datain = ['google','facebook','youtube','twitter']; // the data to be parsed
var response = {pending:0, fordone:false, data:0}; // control object, "data" holds summed response lengths
response.cb = function(){
// if there are pending requests, or the loop isn't ready yet do nothing
if(response.pending||!response.fordone) return;
// otherwise alert.
return when_done.call(null,response.data);
}
for(var i=0; i<datain; i++)(function(i){
response.pending++; // increment pending requests count
$.ajax({url:'http://www.'+datain[i]+'.com', complete:function(r){
response.data+= (r.responseText.length);
response.pending--; // decrement pending requests count
response.cb(); // call the callback
}});
}(i));
response.fordone = true; // mark the loop as done
response.cb(); // call the callback
}());
Esto no es muy elegante, pero hace el trabajo. ¿Hay alguna manera mejor de hacerlo? ¿Quizás un envoltorio?
2 Respuestas
7
JS asíncrono ¡al rescate (tanto para JavaScript del lado del cliente como del lado del servidor)! Su código puede verse así (después de incluir async.js):
var datain = ['google','facebook','youtube','twitter'];
var calls = [];
$.each(datain, function(i, el) {
calls.push( function(callback) {
$.ajax({
url : 'http://www.' + el +'.com',
error : function(e) {
callback(e);
},
success : function(r){
callback(null, r);
}
});
});
});
async.parallel(calls, function(err, result) {
/* This function will be called when all calls finish the job! */
/* err holds possible errors, while result is an array of all results */
});
Por cierto: async tiene otras funciones realmente útiles.
Por cierto 2: tenga en cuenta el uso de $.each
.
contestado el 28 de mayo de 12 a las 11:05
1
Puede utilizar el objeto diferido jQuery para este propósito.
var def = $.when.apply(null, xhrs)
con xhrs
siendo una matriz que contiene los valores de retorno de sus solicitudes $.ajax(). Entonces puedes registrar una devolución de llamada def.done(function() { ... });
y utilice el arguments
objeto similar a una matriz para acceder a las respuestas de las diversas solicitudes. para procesarlos correctamente, elimine su complete
devolver la llamada y agregar dataType: 'text'
y use la siguiente devolución de llamada para done()
:
function() {
var response = Array.prototype.join.call(arguments, '');
// do something with response
}
contestado el 28 de mayo de 12 a las 11:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas javascript callback closures or haz tu propia pregunta.