Examples
First see some examples - scroll below for an explanation.
Callbacks:
Example with async and functions that take Node-style callbacks:
async.parallel([
(cb) => {
setTimeout(() => {
cb(null, 'one');
}, 200);
},
(cb) => {
setTimeout(() => {
cb(null, 'two');
}, 100);
},
],
(err, results) => {
if (err) {
// there was an error:
console.log('Error:', err);
return;
}
// we have ['one', 'two'] in results:
console.log('Results:', JSON.stringify(results));
});
Promises:
Example using functions that return promises - with Bluebird's delay() function:
const { delay } = require('bluebird');
Promise.all([
delay(200, 'one'),
delay(100, 'two'),
]).then((results) => {
// we have ['one', 'two'] in results:
console.log('Results:', JSON.stringify(results));
}).catch((err) => {
// there was an error:
console.log('Error:', err);
});
ES2017 async
/await
:
Using async/await:
const { delay } = require('bluebird');
try {
const results = await Promise.all([
delay(200, 'one'),
delay(100, 'two'),
]);
// we have ['one', 'two'] in results:
console.log('Results:', JSON.stringify(results));
} catch (err) {
// there was an error:
console.log('Error:', err);
}
I'm using JSON.stringify()
to make it explicit what is the format of the data in results
.
Note that even though the first value comes last, the original order is still preserved.
The last example must be run inside of a function declared with an async
keyword, or wrapped in (async () => { ... })()
like this:
(async () => {
try {
const results = await Promise.all([
delay(200, 'one'),
delay(100, 'two'),
]);
// we have ['one', 'two'] in results:
console.log('Results:', JSON.stringify(results));
} catch (err) {
// there was an error:
console.log('Error:', err);
}
})();
Generators and coroutines:
With no support for async
/await
you can use some generator-based coroutines, like those that comes from Bluebird:
const { delay, coroutine } = require('bluebird');
coroutine(function* () {
try {
const results = yield Promise.all([
delay(200, 'one'),
delay(100, 'two'),
]);
// we have ['one', 'two'] in results:
console.log('Results:', JSON.stringify(results));
} catch (err) {
// there was an error:
console.log('Error:', err);
}
})();
Explanation
There are many ways to do that and it all depends on the kind of functions that you want to run.
If you want to run a traditional Node-style functions that take error-first callbacks as their last arguments then the most popular way to run those in parallel or in series is the async
module on npm:
There is no built-in support for things like that in ES6 because those error-first callbacks are really a Node thing, not very popular in JavaScript outside of Node.
The ES6/ES7/ES8 goes in the direction of functions that return promises (instead of functions that take callbacks) and there is a new async
/await
syntax to make them look kind-of-like synchronous, with try/catch working for error handling.
So, the most popular way in Node to combine functions taking callbacks is async module:
To work with promises a popular modules is Bluebird:
For more advanced tasks there is Task.js:
See those answers for more info: