This blog post examines three ways of executing function sequentially:
Synchronous sequential execution is built into JavaScript and looks like this:
function func() {
foo();
bar();
baz();
}
To execute Promise-based functions sequentially, you need to chain function calls via then()
, which is the Promise equivalent of the semicolon:
/**
* Returns a Promise that resolves to `undefined`.
*/
function func() {
return foo()
.then(() => bar())
.then(() => baz());
}
If you are OK with executing the functions in an arbitrary order (the single-threaded version of “in parallel”), you can use Promise.all()
:
/**
* Returns a Promise that resolves to
* [undefined, undefined, undefined].
*/
function func() {
return Promise.all([foo(), bar(), baz()]);
}
The library co also works with Promise based functions. Its helper method, co.wrap()
, converts a generator function gen
into a function that returns a promisification of whatever gen
returns. The neat thing is that gen
can yield
a Promise (e.g. the result of a function call) and is suspended while the Promise is pending. If the Promise is fulfilled, the fulfillment value becomes the result of yield
. If the Promise is rejected, the rejection value is thrown as an exception.
Let’s look at an example:
/**
* The callback implicitly returns `undefined`.
* Therefore, `func` returns a Promise that resolves to
* `undefined`.
*/
const func = co.wrap(function* () {
yield foo();
yield bar();
yield baz();
});
co works very much like async functions, a proposed ECMAScript feature (to appear in ES2016 or later), without being much more verbose. I prefer it to transpiling async functions via Babel, because their syntax may still change.