为什么Promise.resolve()。then()被延迟了?

时间:2015-07-04 22:45:08

标签: javascript promise

我不明白为什么重申了Promise延迟.then()参数调用?

示例:

var myPromise = Promise.resolve();
console.log(myPromise);
myPromise.then(()=>console.log('a'));
console.log('b');

控制台返回:

> Promise { <state>: "fulfilled", <value>: undefined }
> "b"
> "a"

如果符合myPromise,为什么.then()不会调用imediatly解析功能?

2 个答案:

答案 0 :(得分:7)

因为,根据规范,promises在当前执行线程解除并完成“平台代码”之后调用它们的解析处理程序。这保证了它们总是异步调用。

因此,您首先看到console.log('b'),因为该执行线程已完成,然后在您看到console.log('a')的地方调用解析处理程序。

来自Promises/A+ specification

  

2.2.4 onFulfilled或onRejected在执行前不得调用   上下文堆栈仅包含平台代码。 [3.1]。

而且,请注意[3.1]:

  

这里的“平台代码”意味着引擎,环境和承诺   实施代码。在实践中,这个要求确保了这一点   在事件发生后,onFulfilled和onRejected异步执行   循环转入然后调用,并使用新堆栈。这可以   使用“宏任务”机制(如setTimeout或)实现   setImmediate,或者使用“微任务”机制   MutationObserver或process.nextTick。自承诺实施以来   被认为是平台代码,它本身可能包含任务调度   队列或“trampoline”,其中调用处理程序。

这样做是为了提供一致的执行顺序,因此无论何时解析(同步或异步),then()处理程序总是在相对于其他代码的相同时间内被调用。由于许多promises是异步解析的,因此无论如何解决,给定promise的唯一方法就是让它们始终异步调用它们的.then()处理程序。

答案 1 :(得分:5)

jfriend00的回答是正确的。请允许我详细说明原因。我们说我从某个地方得到myPromise。我不知道它只是Promise.resolve可能异步解析,而且可能不会。

myPromise.then(function(){
     console.log("a");
});
console.log("b");

如果异步保证不存在 - 有时记录a b,有时b a。这是竞争条件,是terrible thing to have。承诺不会受到设计的影响 - 并且执行顺序始终保证在新的promises实现和特别是本机承诺中。

运行新作业的实际实施是via Job Queuesthen将作业排入处理程序中的作业队列,并在代码准备好后运行作业队列 - 指定here