async.waterfall = function (/* hlog, */ methods, errorHandler) { var args = arguer(arguments, _waterfallFormat); var hlog = args.hlog || null; var iterator = { fn: null, called: false, allowReinvoke: false }; for (var i = methods.length - 1; i > -1; i--) { iterator = { fn: methods[i], next: iterator, called: false, allowReinvoke: false }; } var context = new WaterfallContext(hlog); process.nextTick(WaterfallRun.bind(context, iterator, errorHandler)); };
async.parallel = function (/* hlog, */ methods, resultsHandler) { var args = arguer(arguments, _parallelFormat); var hlog = args.hlog || null; var waiting = {}; var finished = false; var results = args.methods instanceof Array ? new Array(args.methods.length) : {}; var context = new AsyncContext(hlog); for (var i in args.methods) { if (typeof args.methods[i] !== 'function') continue; waiting[i] = true; args.methods[i].call(context, callback.bind(null, i)); } finished = true; checkDone(); // in case all methods actually ran synchronously. function callback (key, err, result) { delete waiting[key]; results[key] = result; context.log(err); checkDone(); } function checkDone() { if (finished && Object.keys(waiting).length === 0 && typeof args.resultsHandler === 'function') { args.resultsHandler.call(context, context.logChain, results); args.resultsHandler = null; // prevent from being called multiple times } } };