How can i wait for callbacks inside a loop changing a variable, and still using asynchronicity?
The 2nd example is using async, in this case i don't know how to add a 2nd parameter sum to wait, in order to avoid a global var sum. Called like wait(sum,value); with a return value sum
wait is a representation for a complex function, which i use in my real-problem, so it can't be rewritten into "inline"-code and has to stay "function".
Example1:
var _ = require('underscore');
var arr = [1,2,3,4,5,6,7];
var sum = 0;
function wait(item,callback) {
setTimeout(function() {
callback(item);
}, Math.ceil(Math.random()*1000));
}
var done = _.after(arr.length,function(value) {
console.log('sum ='+value);
})
_.each(arr,function(itm) {
wait(itm,function(value) {
console.log('waiting... '+value);
sum = sum + value;
})
// Please wait for the callback
console.log(itm);
done(sum);
});
Example2:
function asyncExample2() {
var async = require('async');
var arr = [1,2,3,4,5,6,7];
function otherWait(item, callback) {
setTimeout(function() {
callback(item); // call this when you're done with whatever you're doing
}, Math.ceil(Math.random()*1000));
}
function wait(item, callback) {
setTimeout(function() {
otherWait(item,function() {
console.log(item);
});
callback(item);
}, Math.ceil(Math.random()*1000));
}
function done() { console.log("sum = "+sum);};
var sum = 0;
async.forEach(arr, wait, done);
}
Desired Call:
sum = wait(sum,item)
The easiest way to do this is putting done in the function wait. It makes done called only after the last callback is executed.
var arr = [1,2,3,4,5,6,7];
var sum = 0;
function wait(item,callback) {
setTimeout(function() {
callback(item);
done(sum);
}, Math.ceil(Math.random()*1000));
}
var done = _.after(arr.length,function(value) {
console.log('sum ='+value);
})
_.each(arr,function(itm) {
wait(itm,function(value) {
console.log('waiting... '+value);
sum = sum + value;
})
// Please wait for the callback
console.log(itm);
//done(sum);
});
Output:

Underscore is entirely synchronous so done(sum) would execute before wait has finished executing.
For asynchronous operation don't use underscore.
Something simple like this should do what you want:
var sum = 0;
var waitNext = function(pos) {
wait(arr[pos], function(value)) {
if(pos < arr.length)
{
console.log('waiting... '+value);
sum += value;
waitNext(pos+1);
}
else
{
done(sum);
}
}
}
waitNext(0);
You could of course avoid using waitNext and just modify wait but this will work if wait is not your code.
Not sure if you'd want sum += value inside the if or just before it since now there's an unnecessary waitNext call you could remove by tweaking the if condition's order.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With