Is there a better way to do this?
let foo;
return functionA().then(result => {
foo = result;
return functionB();
}).then(bar => {
return functionC(foo, bar);
});
Notice that the result of functionA
is required input to functionC
. Using a variable outside the promise scope works fine, but it feels kinda icky. Is there a clean idiomatic way to do this?
Please note that I do not have the opportunity to change the API of any of the functions I am calling.
Often Promise. all() is thought of as running in parallel, but this isn't the case. Parallel means that you do many things at the same time on multiple threads. However, Javascript is single threaded with one call stack and one memory heap.
Example 2: Chaining the Promise with then() Promise resolved You can call multiple functions this way. In the above program, the then() method is used to chain the functions to the promise. The then() method is called when the promise is resolved successfully. You can chain multiple then() methods with the promise.
The fulfillment value is an array of fulfillment values, in the order of the promises passed, regardless of completion order. If the iterable passed is non-empty but contains no pending promises, the returned promise is still asynchronously (instead of synchronously) fulfilled.
You could try using Promise.all()
which you can pass an array of promises and it provides an array of responses within the then()
callback when all promises passed in have resolved. You can access those array values to pass into functionC
:
Promise.all([functionA, functionB]).then(values => functionC(values[0], values[1]));
Might be a little cleaner (without nesting) as it doesn't look like the response from functionA
needs to be passed into functionB
.
Otherwise, nesting would look like:
return functionA().then(foo => {
return functionB().then(bar => {
return functionC(foo, bar);
});
});
One option is, as Alexander Staroselsky writes, to use Promise.all(functionA(), functionB())
. This runs the two functions simultaneously. If that's what you want to happen, you can use that answer. If, however, you want them to happen one after the other and then also be able to pass the result onto another handler, you can do this:
function functionA() {
return new Promise(resolve => resolve(1));
}
function functionB() {
return new Promise(resolve => resolve(2));
}
function functionC(first, second) {
return first + second;
}
functionA()
.then(result => Promise.all([result, functionB()]))
.then(function([first, second]) {
return functionC(first, second);
})
.then(result => {
console.log(result);
});
The functions are obviously simplified -- but the lovely thing about Promises is that that doesn't matter: we don't care how complex they are or how long they take. Yay Promises!
The clever thing is that Promise.all
doesn't mind if the values you pass are not Promises. If they are any other value, they are treated as a Promise that is resolved immediately. (In the same way that you can do Promise.resolve(42).then(...)
.) So we can do Promise.all([result, functionB()])
. This says "give me a Promise that is resolved when you have a final value for both result
and functionB()
and pass both values on". That is immediately in the case of result
and at some unspecified time in the case of functionB
.
The returned values are then passed as an array to the next then
function.
.then(function([first, second]) {
return functionC(first, second);
})
This then receives the values as an array (see the use of destructuring in the parameter list) and sends those values on to functionC
. We then do one last then
function to show the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With