scott scott - 11 days ago 8
Javascript Question

Concurrent chained javascript promises

I have javascript promises A and C where B is a function that returns a promise. This is how I'd like them to flow:

A--->B--->
C-------->
D------>


B utilizes output from A, and D utilizes output from B and C

My current code looks roughly as so:

var runPromises = [];
runPromises.push(A.then(B));
runPromises.push(C);

Promise.all(runPromises).then(values => console.log(values));


What I'm seeing happen is A and C execute but B does not until after A and C are logged out. What is the proper pattern here for execution? Do A and B need to be put in an encompassing promise?

Answer

if A, B and C are promises, then A.then(B) will return A as the result. The argument to .then must be FUNCTION, not a promise

What you want to do is something like

Promise.all([A.then(result=>B), C]).then(values => console.log(values));

If B is a FUNCTION (as per the comment below) rather than a PROMISE (as per the question), it's a simple change:

Promise.all([A.then(result=>B()), C]).then(values => console.log(values));
//---------------------------^^

or more simply

Promise.all([A.then(B), C]).then(values => console.log(values));

which is basically what you had in the question - so I'm now confused as to what the problem is? Is it the values shown in the console.log?

var delay = (timeout, value) => new Promise(resolve => {
    setTimeout(() => {resolve(value); console.log('done', value);}, timeout); 
    console.log('begin', value)
});


var A = delay(3000, 'valueOfA'); // A is a Promise
var C = delay(2000, 'valueOfC'); // C is a Promise
var B = valA => {
    console.log('B called with', valA);
    return delay(1000, valA + ':valueOfB'); // include valA to show that the resolved value of B depends on the resolved value of A
} // B is a function that returns a Promise and uses the resolved value of A as input
Promise.all([A.then(B),C]).then(values => console.log(values));