Promises are really simple to use when passing a single argument from the first operation to the next one. What if we need to pass multiple arguments? For example, imagine we need to generate two numbers and then sum them up, all in an asynchronous manner. We can write these simple functions to start:
var Q = require('q');
If we need to perform each operation in sequence, we get back to the original pyramid of doom of nested callbacks.
The pyramid is necessary to keep
b in the lexical scope for the last step (calling
We can simplify the pyramid a little if we are allowed to run
getB in parallel
We are using Q.all method
to execute multiple promises in parallel and get a single promise back that resolves with an array.
ab array passed to the next step has the result of each individual promise in the same order as the promises
Taking it one step further, there is
that can be used after
Q.all to separate results into individual arguments.
Q.all().then(fn) as executing
fn.call(null, [results]), while
We can even skip the intermediate function and call the
sum directly using
Using the original pure function,
sum is very convenient, because we can still apply
the partial application to prefill some arguments. For example to always add 2 to the number returned from
we can use either the initial step or the partial application
Let us go back to the original sequence where we executed
getB in sequence.
We can use
Q.spread to pass extra arguments to the next step without using an object or
All we have done here was to push the promise returned by
getB to the array returned by
then we spread into
sum arguments. Compare this solution to the original pyramid-like solution at the beginning
of this post. We are not relying on the lexical scope any more, and we keep the promise chain very flat.
Imagine we want to print both operands and the result instead of printing the result only.
Update - ES6
Promise.all([p1, p2, p3])