在评估Promise.all的结果时使用没有超时值的setTimeout

时间:2018-09-27 19:27:45

标签: javascript asynchronous promise settimeout es6-promise

Promise.all MDN docs包含一个评估多个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 }

有人可以用比代码中注释更多的单词来帮助解释这一点吗?

2 个答案:

答案 0 :(得分:2)

没有延迟值调用的

setTimeout只是将传入的函数放在要由the JavaScript event loop执行的队列上。通常这是下一个刻度,尽管队列中可能已经安排了其他事项,所以该功能将排在这些之后。

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

演示程序流程:

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

答案 1 :(得分:0)

在JavaScript中,promise的优先级高于超时,因此从理论上讲,它们应全部实现并准备在超时中的函数执行时被记录下来。