【问题标题】:What's the execution sequence of promise in javascript?javascript中promise的执行顺序是什么?
【发布时间】:2018-02-14 08:17:30
【问题描述】:

我对这段代码的输出感到困惑。 输出为4 3 2 1

我如何理解流程?

new Promise(resolve => {
    resolve(1);
    Promise.resolve().then(() => console.log(2));
    console.log(4);
}).then( t => console.log(t) );
console.log(3);

【问题讨论】:

  • 同步代码保持同步,异步代码保持异步——你可以从输出中看到console.log的执行顺序
  • 1, 2, 3(最多 .then),4, 5(最多 .then) 6,3(代码在 .then),5(代码在 .then) - 或者,请参阅jsfiddle.net/gzy6ncz3
  • 您期望的输出是什么? this 回答中有视频和一些文档的链接,可以提供帮助。
  • 想到resolve() 做类似setTimeout(later, 0) 的事情,其中​​later 是使用then 注册的函数,这可能是一个很好的方法来推理正在发生的事情,不是吗?我的意思是说这是asynchronous。它被推送到事件循环对吗?

标签: javascript promise


【解决方案1】:

我认为关键的理解是

  • new Promise 回调始终被同步调用(在调用期间)
  • then 回调总是异步调用(稍后)

因此,这里的各个同步步骤按顺序排列:

new Promise(resolve => { // begins creating a promise
    resolve(1);          // fulfills the promise
    Promise.resolve()    // creates a promise
    .then(…);            // registers a callback
    console.log(4);      // logs the first line
})                       // finishes the promise creation
.then(…);                // registers a callback
console.log(3);          // logs the second line

当注册回调时,then 检查承诺是否已经解决,这就是这里的情况(对于两个承诺),它会立即通过将它们放入队列来安排它们。理论上这个队列定义了一个特定的顺序,实际上你应该忽略它(即同时安排的事情可以以任何顺序发生)。如果您想要特定的订单,请始终创建明确的承诺链,而不是依赖内部排队。

所以这里我们有两个预定项目:

() =>          // the first item is called with undefined (result of `Promise.resolve()`)
console.log(2) // logs the third line

t =>           // the second item is called with 1 (from the `resolve(1)` call)
console.log(t) // logs the fourth line

【讨论】:

    【解决方案2】:

    这取决于Promise 的实现方式。 Promises/A+ specification 需要使用then 注册的函数,比如later,才能完成asynchronously

    因此,考虑 resolve(1) 执行以下类似操作可以帮助您推理上述 cmets 中解释的 asynchronous 流程:

    1. promise 的值设置为1
    2. 注册一个setTimeout(later, 0),后面是函数 由then注册

    setTimeout 是关键,它只是将其推送到event-loop,而不是立即执行,因为规范是这样说的。

    所以,

    new Promise(resolve => {
        resolve(1);
        Promise.resolve().then(() => console.log(2));
        console.log(4);
    }).then( t => console.log(t) );
    console.log(3);
    
    console.log(2) // gets queued
    console.log(4) // gets executed
    console.log(3) // gets executed
    console.log(1) // gets queued
    

    您可以在此处查看相关问题:Why do Promise libraries use event loops?

    【讨论】:

      猜你喜欢
      • 2016-08-20
      • 1970-01-01
      • 2011-10-10
      • 1970-01-01
      • 2018-07-21
      • 2018-03-24
      • 2016-08-07
      • 2020-03-13
      相关资源
      最近更新 更多