Asíncrono para ciclo en JavaScript
Necesito un bucle que espere una llamada asíncrona antes de continuar. Algo como:
for ( /* ... */ ) {
someFunction(param1, praram2, function(result) {
// Okay, for cycle could continue
})
}
alert("For cycle ended");
¿Cómo podría hacer esto? ¿Tienes alguna idea?
Aceptado
No puede mezclar sincrónico y asincrónico en JavaScript si bloquea el script, bloquea el navegador.
Tienes que seguir el camino completo del evento aquí, afortunadamente podemos ocultar las cosas feas.
EDITAR: Se actualizó el código.
function asyncLoop(iterations, func, callback) {
var index = 0;
var done = false;
var loop = {
next: function() {
if (done) {
return;
}
if (index < iterations) {
index++;
func(loop);
} else {
done = true;
callback();
}
},
iteration: function() {
return index - 1;
},
break: function() {
done = true;
callback();
}
};
loop.next();
return loop;
}
Esto nos proporcionará un asincrónico loop
; por supuesto, puede modificarlo aún más para tomar, por ejemplo, una función para verificar la condición del bucle, etc.
Ahora vamos a la prueba:
function someFunction(a, b, callback) {
console.log('Hey doing some stuff!');
callback();
}
asyncLoop(10, function(loop) {
someFunction(1, 2, function(result) {
// log the iteration
console.log(loop.iteration());
// Okay, for cycle could continue
loop.next();
})},
function(){console.log('cycle ended')}
);
Y la salida:
Hey doing some stuff!
0
Hey doing some stuff!
1
Hey doing some stuff!
2
Hey doing some stuff!
3
Hey doing some stuff!
4
Hey doing some stuff!
5
Hey doing some stuff!
6
Hey doing some stuff!
7
Hey doing some stuff!
8
Hey doing some stuff!
9
cycle ended
Simplifiqué esto:
FUNCIÓN:
var asyncLoop = function(o){
var i=-1;
var loop = function(){
i++;
if(i==o.length){o.callback(); return;}
o.functionToLoop(loop, i);
}
loop();//init
}
USO:
asyncLoop({
length : 5,
functionToLoop : function(loop, i){
setTimeout(function(){
document.write('Iteration ' + i + ' <br>');
loop();
},1000);
},
callback : function(){
document.write('All done!');
}
});
EJEMPLO: http://jsfiddle.net/NXTv7/8/