首页 > 解决方案 > 在评估 Promise.all 的结果时使用没有超时值的 setTimeout

问题描述

Promise.all MDN 文档包含一个评估多个Promise.all结果的示例,但在一个setTimeout没有超时值的函数内。

从文档:

// 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 }

有人可以用比代码中的注释多几句话来帮助解释这是什么结果吗?

标签: javascriptasynchronouspromisesettimeoutes6-promise

解决方案


setTimeout没有延迟值的调用只是将传入的函数放在队列中以由JavaScript 事件循环执行。这通常是下一个滴答声,尽管队列中可能已经安排了其他事情,所以函数将在这些事情之后。

通过将 Promise 解决方案放在队列中,类似地安排它。这意味着将在 Promise 完成setTimeout立即安排功能完成。反过来,这意味着 , 和 的值将在JavaScript 事件循环的当前运行中挂起,然后在调用延迟的函数时处于最终状态。pp2p3setTimeout

演示程序的流程:

//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.
});


推荐阅读