【问题标题】:Why Promise.resolve().then() is delayed?为什么 Promise.resolve().then() 被延迟了?
【发布时间】:2015-10-03 01:09:12
【问题描述】:

我不明白为什么解决了 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()不立即调用resolve函数?

【问题讨论】:

    标签: javascript promise


    【解决方案1】:

    因为按照规范,在当前执行线程展开并完成返回“平台代码”之后,promise 会调用它们的解析处理程序。这保证了它们总是被异步调用。

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

    来自Promises/A+ specification

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

    还有,这里的注释 [3.1]:

    这里的“平台代码”是指引擎、环境和承诺 实现代码。在实践中,这一要求确保 onFulfilled 和 onRejected 在事件之后异步执行 循环调用 then ,并使用新堆栈。这可以是 使用“宏任务”机制实现,例如 setTimeout 或 setImmediate,或使用“微任务”机制,例如 MutationObserver 或 process.nextTick。自承诺实施以来 被认为是平台代码,它本身可能包含一个任务调度 调用处理程序的队列或“蹦床”。

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

    【讨论】:

      【解决方案2】:

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

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

      如果不存在异步保证 - 有时会记录a b,有时会记录b a。这是一个竞争条件,是一个terrible thing to have。 Promise 在设计上不容易受到这个问题的影响 - 并且在新的 Promise 实现和本机 Promise 中,执行顺序总是得到保证。

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

      【讨论】:

        猜你喜欢
        • 2021-11-30
        • 1970-01-01
        • 2018-06-24
        • 1970-01-01
        • 2015-02-27
        • 1970-01-01
        • 2017-01-15
        • 1970-01-01
        • 2021-08-14
        相关资源
        最近更新 更多