Reputation: 28
the following function is an abstracted version of a little bit more complex function im working on. Can someone tell me why the callback of async.parallel returns a different value for the allitems array than waterfallfunction2 which return the array i expected?
var async = require('async');
async.waterfall([
//Waterfallfunction 1
function(callback) {
var allitems = [];
async.parallel([
//Parallel 1
function(callback) {
console.log("Waterfall 1 -> parallel 1");
async.each([1, 2, 3, 4, 5, 6], function(item, callback) {
allitems.push(item * 3);
callback(null);
}, callback(null));
},
//Parallel 2
function(callback) {
console.log("Waterfall 1 -> parallel 2");
async.each([1, 2, 3], function(item, callback) {
allitems.push(item * 3 * 9);
callback(null);
}, callback(null));
},
//Parallel 3
function(callback) {
console.log("Waterfall 1 -> parallel 3");
async.each([1, 2, 3, 4, 5, 6, 7, 8, 9], function(item, callback) {
allitems.push(item * 2);
callback(null);
}, callback(null));
}
],
//Callback parallel completed
function(err, results) {
if (err) {
callback(err);
}
console.log("Waterfall 1 parallel completed");
//I expect all item to be
//[ 3, 6, 9, 12, 15, 18, 27, 54, 81, 2, 4, 6, 8, 10, 12, 14, 16, 18 ]
console.log(allitems);
// but it logs
// [ 3, 6, 9, 12, 15, 18, 27, 54, 81 ]
//pass allitems to the next function in waterfall
callback(null, allitems);
});
},
// Waterfallfunction2
//calculate items length
function(allitems, callback) {
var itemlength = allitems.length;
//pass itemlength to next function
callback(null, itemlength);
},
//Waterfallfunction3
//Log Message
function(itemlength, callback) {
console.log("The array is " + itemlength + " long");
callback(null);
}
],
//Callbackfunction on Waterfall completed
function(err, result) {
if (err) {
console.log(err);
}
console.log("operations completed!");
});
Upvotes: 0
Views: 810
Reputation: 14982
It is too hard to read your callback hell...
I try to write same thing and all works :)
var async = require('async');
var cascade1 = function(next) {
var all = [];
async.parallel([
function task1(next) {async.each([1, 2, 3], function(i, next){all.push(i);next();}, next) },
function task2(next) {async.each([1, 2, 3], function(i, next){all.push(2*i);next();}, next) },
function task3(next) {async.each([1, 2, 3], function(i, next){all.push(3*i);next();}, next) },
], function(){
next(null, all);
});
};
var cascade2 = function (items, next) {
console.log(items);
next(null, items.length);
}
async.waterfall([cascade1, cascade2], function(err, len){
console.log(err, len);
});
I found a bug! You are call callback instead of passing it in parallels calls! =)
Just change callback(null)
to callback
where you want to pass callback.
Upvotes: 1
Reputation: 239
You shouldn't call callback(null) directly as the third param in async.each(). You are in fact calling a callback 2 levels up by doing callback(null) directly. Instead you should wrap that call inside a function so it works as you think.
This works fine:
var async = require('async');
async.waterfall([
//Waterfallfunction 1
function(callback) {
var allitems = [];
async.parallel([
//Parallel 1
function(callback) {
console.log("Waterfall 1 -> parallel 1");
async.each([1, 2, 3, 4, 5, 6], function(item, callback) {
allitems.push(item * 3);
callback(null);
}, function() {callback(null)});
},
//Parallel 2
function(callback) {
console.log("Waterfall 1 -> parallel 2");
async.each([1, 2, 3], function(item, callback) {
allitems.push(item * 3 * 9);
callback(null);
}, function() {callback(null)});
},
//Parallel 3
function(callback) {
console.log("Waterfall 1 -> parallel 3");
async.each([1, 2, 3, 4, 5, 6, 7, 8, 9], function(item, callback) {
allitems.push(item * 2);
callback(null);
}, function() {callback(null)});
}
],
//Callback parallel completed
function(err, results) {
if (err) {
callback(err);
}
console.log("Waterfall 1 parallel completed");
//I expect all item to be
//[ 3, 6, 9, 12, 15, 18, 27, 54, 81, 2, 4, 6, 8, 10, 12, 14, 16, 18 ]
console.log(allitems);
// but it logs
// [ 3, 6, 9, 12, 15, 18, 27, 54, 81 ]
//pass allitems to the next function in waterfall
callback(null, allitems);
});
},
// Waterfallfunction2
//calculate items length
function(allitems, callback) {
var itemlength = allitems.length;
//pass itemlength to next function
callback(null, itemlength);
},
//Waterfallfunction3
//Log Message
function(itemlength, callback) {
console.log("The array is " + itemlength + " long");
callback(null);
}
],
//Callbackfunction on Waterfall completed
function(err, result) {
if (err) {
console.log(err);
}
console.log("operations completed!");
});
Upvotes: 0