Let's say I have this async.parallel
code example below, to run async functions in parallel and wait for them to complete before running code on results.
async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
/* … continued code */
debug(results) // prints "results" object successfully without problems
});
What I want to do is to put continued code (code to continue/run after all functions passed to async.parallel
are completed) outside async.parallel
.
I tried this:
const results = await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
debug("test print1: from inside async.parallel callback function");
// called/printed after "test print2" meaning that async.parallel isn't awaited.
return results;
});
/* … continued code */
debug("test print2: from outside async.parallel");
// printed before "test print1" meaning that async.parallel isn't awaited.
debug(results) // prints "undefined"
And this:
let results_outer;
await async.parallel({
one: async (callback) => {/* ... some async code */ return someResult},
two: async (callback) => {/* ... some async code */ return someResult},
three: async (callback) => {/* ... some async code */ return someResult},
},(err,results) => {
if (err) { /* … error handling code */ }
debug("test print1: from inside async.parallel callback function");
// printed after "test print2" meaning that async.parallel isn't awaited.
results_outer = results;
});
/* … continued code */
debug("test print2: from outside async.parallel");
// printed before "test print1" meaning that async.parallel isn't awaited.
debug(results_outer) // prints "undefined"
My question is, How can I await async.parallel
and get results object successfuly?
Suggested Solutions/Alternatives: (Non is yet a solution for my question, however they may be useful temporary alternatives)
Alternative 1: (I don't prefer because it seems uglier/cumbersome than async.parallel)
const results = await Promise.all([
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 1')} ),
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 2')} ),
new Promise( (resolve, reject) => {/* ... some async code */ resolve('some result 3')} )
]);
debug(results); // prints "results" object successfully without problems
Note on Alternative 1:
To make Alternative 1 simpler, we can create promisify(some_function)
:
const results = await Promise.all([
promisfy(some_functionOne),
promisfy(some_functionTwo),
promisfy(some_functionThree)
]);
debug(results); // prints "results" object successfully without problems
function promisfy(some_function) {
const promise = new Promise( (resolve, reject) => {
some_function_return_value = await some_function();
resolve(some_function_return_value);
} );
return promise;
}
To simplify Alternative 1 further:
async_parallel([some_functionOne, some_functionTwo, some_functionThree]);
debug(results); // prints "results" object successfully without problems
function async_parallel(functions_to_run) {
let promises = functions_to_run.map(function_to_run => promisfy(function_to_run));
const results = await Promise.all(promises);
return results;
}
We may end up building a similar library to async library and reinvent the wheel, specially when we need features like concat, waterfall, etc.