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

Yuk*_*élé 6 javascript promise

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

例:

var myPromise = Promise.resolve();
console.log(myPromise);
myPromise.then(()=>console.log('a'));
console.log('b');
Run Code Online (Sandbox Code Playgroud)

控制台返回:

> Promise { <state>: "fulfilled", <value>: undefined }
> "b"
> "a"
Run Code Online (Sandbox Code Playgroud)

如果myPromise满足,为什么.then()不调用imediatly解决功能?

jfr*_*d00 7

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

因此,您可以看到第console.log('b')一个执行线程完成,然后在您看到的情况下调用解析处理程序console.log('a').

来自Promises/A +规范:

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

而且,这里的注释[3.1]:

这里的"平台代码"意味着引擎,环境和承诺实现代码.实际上,这个要求确保onFulfilled和onRejected异步执行,然后调用事件循环,然后调用新堆栈.这可以使用诸如setTimeout或setImmediate之类的"宏任务"机制,或者使用诸如MutationObserver或process.nextTick之类的"微任务"机制来实现.由于promise实现被认为是平台代码,因此它本身可能包含一个任务调度队列或"trampoline",其中调用处理程序.

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


Ben*_*aum 5

jfriend00的回答是正确的.请允许我详细说明原因.假设我是myPromise从某个地方来的.我不知道它只是一个Promise.resolve,它可能异步解决,也可能不会.

myPromise.then(function(){
     console.log("a");
});
console.log("b");
Run Code Online (Sandbox Code Playgroud)

如果异步保证不存在 - 有时会记录a b,有时也会记录b a.这是一种竞争条件,并且是一件非常糟糕的事情.承诺不会受到设计的影响 - 并且执行顺序总是在新的promises实现和特别是本机承诺中得到保证.

运行新作业的实际实施是通过作业队列.then将作业排入处理程序中的作业队列,并在代码准备好后运行作业队列 - 这在此处指定.