Reputation: 3753
I'm really struggling to get arrays iterated in a certain order and each one should finish before the next can start. I've tried using async.series and async.each but the results are not as I expected them.
I have this code:
var async = require('async');
var abc = ['a', 'b', 'c'];
// Step 1
function one(callback) {
async.each(abc, function(issue, callback) {
setTimeout(function(){
issue += '1';
console.log('Processing issue ' + issue);
}, 2000);
callback();
}, function(err) {
if(err) {
console.log('Fail 1');
} else {
console.log('Success 1');
}
});
}
// Step 2
function two(callback) {
async.each(abc, function(issue, callback) {
setTimeout(function(){
issue += '2';
// Perform operation on file here.
console.log('Processing issue ' + issue);
}, 2000);
callback();
}, function(err) {
if(err) {
console.log('Fail 2');
} else {
console.log('Success 2');
}
});
}
// Step 3
function three(callback) {
async.each(abc, function(issue, callback) {
setTimeout(function(){
issue += '3';
// Perform operation on file here.
console.log('Processing issue ' + issue);
}, 2000);
callback();
}, function(err) {
if(err) {
console.log('Fail 3');
} else {
console.log('Success 3');
}
});
}
async.series([
function(callback) {
console.log('step 1 in async.series');
one(callback);
callback();
},
function(callback) {
console.log('step 2 in async.series');
two(callback);
callback();
},
function(callback) {
console.log('step 3 in async.series');
three(callback);
callback();
}
], function(err) {
if(err) return next(err);
console.log('Done:');
});
Result:
step 1 in async.series
Success 1
step 2 in async.series
Success 2
step 3 in async.series
Success 3
Done:
//After two second timeout all below happens at once
Processing issue a1
Processing issue b1
Processing issue c1
Processing issue a2
Processing issue b2
Processing issue c2
Processing issue a3
Processing issue b3
Processing issue c3
Expected:
step 1 in async.series
//Expected below after two second timeout
Processing issue a1
Processing issue a2
Processing issue a3
Success 1
step 2 in async.series
//Expected below after two+two second timeout
Processing issue b1
Processing issue b2
Processing issue b3
Success 2
step 3 in async.series
//Expected below after two+two+two second timeout
Processing issue c1
Processing issue c2
Processing issue c3
Success 3
Done:
What should I do instead to get expected results??
Thanks!
Upvotes: 2
Views: 681
Reputation: 17168
Put all of those callback()s inside the setTimeout()s. Then everything should work as you'd expect.
Edit: Each step should look similar to this:
// Step 1
function one(done) {
console.log('step 1 in async.series');
async.each(abc, function(issue, callback) {
setTimeout(function(){
issue += '1';
console.log('Processing issue ' + issue);
callback();
}, 2000);
}, done);
}
And the actual series should look like this:
async.series([one, two, three], function(err, data){
if (err !== null) {
console.log(data);
} else {
console.error(err);
}
});
Upvotes: 2
Reputation: 5964
async.each
happens in parallel, so all of these function get ran at the same time. You are looking for the async.eachSeries
method: https://www.npmjs.com/package/async#eachseries-arr-iterator-callback
The same as each, only iterator is applied to each item in arr in series. The next iterator is only called once the current one has completed. This means the iterator functions will complete in order.
Upvotes: 2