The Promise.all MDN docs contain an example of evaluating multiple Promise.all
results, but within a setTimeout
function without a timeout value.
From the docs:
// this will be counted as if the iterable passed is empty, so it gets fulfilled
var p = Promise.all([1,2,3]);
// this will be counted as if the iterable passed contains only the resolved promise with value "444", so it gets fulfilled
var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// this will be counted as if the iterable passed contains only the rejected promise with value "555", so it gets rejected
var p3 = Promise.all([1,2,3, Promise.reject(555)]);
// using setTimeout we can execute code after the stack is empty
setTimeout(function() {
console.log(p);
console.log(p2);
console.log(p3);
});
// logs
// Promise { <state>: "fulfilled", <value>: Array[3] }
// Promise { <state>: "fulfilled", <value>: Array[4] }
// Promise { <state>: "rejected", <reason>: 555 }
Can someone help explain what this achieves, with a few more words than the comment in the code?
setTimeout
called with no delay value just puts the passed in function on the queue to be executed by the JavaScript event loop. That is usually the next tick, although there could be other things on the queue already scheduled, so the function will be after those.
Promise resolution gets scheduled similarly by putting it on the queue. That means setTimeout
will schedule the function completion immediately after the promises are finalized. In turn, this means that the value of p
, p2
, and p3
will be pending in the current run of the JavaScript event loop, then in the final state when the function delayed by setTimeout
is called.
Demonstrating the flow of the program:
//console.logs from StackOverflow snippets don't print the state of the promise
//you can open the browser developer tools and click the button to run the snippet
//in order to see that output
var p = Promise.all([1,2,3]); //<-- a pending promise is created
p.finally(() => console.log("promise fulfilled", p));
console.log("this call is executed immediately", p); //<-- the same run of the event loop
setTimeout(function() {
console.log("this call is scheduled to execute in the future", p); //<-- to be executed in a subsequent run of the loop.
});
In JavaScript promises have a higher priority than timeouts so in theory they should all be fulfilled and ready to be logged by the time the function in the timeout is executed.