admin管理员组文章数量:1331538
So I have a nice chunk of nested async code running together and it all seems to be okay, except for when I get to the end of it. my last function in a series block is a forEach: that then goes into a async.parallel
Managed to track down the following chunk which does not run in order:
async.forEach(array, function(elem, callback) {
async.parallel([
function(callback) {
database-call-A(elem, unction(err, data) {
if(err){
console.log("error on first parallel");
callback({err: false}); // will break out
} else {
elem.c = data;
callback();
}
});
},
function(callback) {
database-call-B(elem, function(err, data) {
if(err){
console.log("error on first parallel");
callback({err: false}); // will break out
} else {
elem.c = data;
callback();
}
});
}
]); // end async.parallel
// if forEach needs a callback after every iteration (which I think it does?)
console.log("PRINTS N TIMES - ONCE FOR EVERY ITERATION");
callback(); // both parallel functions have run, call back forEach
}); // end forEach
console.log("Donions - prints when finished");
When I tested this code by throwing print statements everywhere, I noticed that "PRINTS N TIMES ..." ran N times, then I got "Donions .." and THEN my do something(); and other stuff(); started getting called in my async.parallel.
Why is my forEach iterating through without waiting for the callbacks from async.parallel?
So I have a nice chunk of nested async code running together and it all seems to be okay, except for when I get to the end of it. my last function in a series block is a forEach: that then goes into a async.parallel
Managed to track down the following chunk which does not run in order:
async.forEach(array, function(elem, callback) {
async.parallel([
function(callback) {
database-call-A(elem, unction(err, data) {
if(err){
console.log("error on first parallel");
callback({err: false}); // will break out
} else {
elem.c = data;
callback();
}
});
},
function(callback) {
database-call-B(elem, function(err, data) {
if(err){
console.log("error on first parallel");
callback({err: false}); // will break out
} else {
elem.c = data;
callback();
}
});
}
]); // end async.parallel
// if forEach needs a callback after every iteration (which I think it does?)
console.log("PRINTS N TIMES - ONCE FOR EVERY ITERATION");
callback(); // both parallel functions have run, call back forEach
}); // end forEach
console.log("Donions - prints when finished");
When I tested this code by throwing print statements everywhere, I noticed that "PRINTS N TIMES ..." ran N times, then I got "Donions .." and THEN my do something(); and other stuff(); started getting called in my async.parallel.
Why is my forEach iterating through without waiting for the callbacks from async.parallel?
Share Improve this question edited Dec 17, 2013 at 12:07 gadu asked Dec 17, 2013 at 10:58 gadugadu 1,8261 gold badge18 silver badges32 bronze badges 02 Answers
Reset to default 4First, there is no async.forEach
, but there is the async.each
function. The async.parallel
function will execute all tasks simoultaneously and then execute the callback if it was defined.
In your source, the callback
function will be executed as soon as the async.parallel
is executed, not after all of it's functions have returned. I suggest you read the documentation.
If you want to execute the callback
after all the parallel functions' callbacks have been called, you should pass the forEach
's callback to the async.parallel
function as a second parameter, after the array of functions. Also, you should probably pass the callbacks to both databaseCallA
and databaseCallB
thus making them call their callbacks when they finish so they aren't executed prematurely.
async.each(array, function(elem, callback) {
async.parallel([
function(cb) {
databaseCallA(cb);
// if you have called the cb here, the `async.parallel` function would "think" that the databaseCallA has finished, even though it may not have started yet.
},
function(cb) {
databaseCallB(cb):
}
], callback);
});
You should modify your database call functions to accept the callback argument and make them call the callback after they have done their work.
The point of async calls is to free the resources for other jobs while waiting for your job to finish - your code will continue it's execution, but you can use the callbacks or some kind of event-based notifications to notify others your async job has finished.
EDIT
To execute something after all parallel calls have finished:
async.each(array, function(elem, callback) {
async.parallel([
function(cb) {
// I use the setTimeout function to intentionally
// delay the response
setTimeout(function() {
// the first cb parameter is error, the second is result
// in case there was no error
cb(undefined, 'a');
}, 500);
},
function(cb) {
setTimeout(function() {
cb(undefined, 'b');
}, 300);
},
function(cb) {
setTimeout(function() {
cb(undefined, 'c');
}, 800);
}
], function(err, results) {
// this will be executed only after all three cb's are executed. In
// this case, after about 800ms. The results variable will be an
// array containing the resuts passed to each cb. In this case it
// will be ['a', 'b', 'c'].
// you could call the main callback here
callback();
});
}, function(err) {
// this callback will be executed either after everything was done,
// or if an error has occurred.
if (err) {
handleError(err);
return;
}
// this should be executed after all `each` and `parallel` calls
// have finished. In this case, it should also be after about 800ms
// from the start, since everything was executed in parallel
console.log('finished');
// now you are sure everything was done, do something afterwards
after();
});
// this will be executed immediately so don't put anything here
// that depends on the oute of the async calls above
console.log('test');
I'm not sure for this answer, but according with async documentation, I think you must do this :
async.forEach(array, function(elem, callback) {
async.parallel([
function(callback) {
database-call-A();
callback();
},
function(callback) {
database-call-B():
callback(); // callback for second parallel function
}
], function(err,result) {
// this code is executed when paralles functions ends
console.log("PRINTS N TIMES - ONCE FOR EVERY ITERATION");
callback();
}); // end async.parallel
}); // end forEach
regards.
本文标签: javascriptusing async correctly (with forEach)Stack Overflow
版权声明:本文标题:javascript - using async correctly (with forEach) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742282863a2446416.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论