如何理解此Promise执行顺序?

Leo*_*Shi 4 javascript promise

我不明白为什么这段代码会产生这样的顺序?有人可以详细说明吗?我以为Promises就像一个FIFO队列,但是嵌套的Promise函数似乎有点不可预测,或者使用其他数据结构吗?

new Promise(resolve => {
    resolve()
  })
  .then(() => {
    new Promise(resolve => {
        resolve()
      })
      .then(() => {
        console.log(1)
      })
      .then(() => {
        console.log(2)
      })
      .then(() => {
        console.log(3.1)
      })
  })
  .then(() => {
    console.log(1.1)
    new Promise((resolve => {
        resolve()
      }))
      .then(() => {
        new Promise(resolve => {
            resolve()
          })
          .then(() => {
            console.log(4)
          })
          .then(() => {
            console.log(6)
          })
      }).then(() => {
        console.log(5)
      })
  }).then(() => {
    console.log(3)
  })
console.log(0)
Run Code Online (Sandbox Code Playgroud)

输出:

0
1
1.1
2
3
3.1
4
5
6
Run Code Online (Sandbox Code Playgroud)

Gib*_*bor 7

承诺是异步的。这意味着每次创建新的Promise时,新的异步操作就会开始。

JS中的异步操作是什么?首先,您需要了解无论您做什么,JS都在单个线程上运行。因此,为了使其看起来像异步的,有一个叫做“事件循环”的东西(将注释的链接链接到原始的帖子,tnx @Taki作为很好的来源)。

通常,事件循环在主代码动作之间的动作中存储所有异步功能和“清单”。这确实是过度简化的解释,请参阅链接以了解更多信息,但这就是要点。

因此,基本上,这里没有“ FIFO”队列-异步功能的顺序实际上取决于处理器速度,操作系统等因素。

但是,有一种方法可以确保一个异步操作仅在另一个异步操作完成后才执行,这就是该.then子句。事实是,它仅确保在.then将其链接到特定的promise之后将执行将要执行的特定功能,但是它并没有说明事件循环中其他异步操作(promises)的顺序。因此,例如在您的代码中:

new Promise(resolve => {
    resolve() // PROMISE A
  })
  .then(() => {
    new Promise(resolve => {
        resolve() // PROMISE B
      })
      .then(() => {
        console.log(1) //PROMISE C
      })
      .then(() => {
        console.log(2)
      })
      .then(() => {
        console.log(3.1)
      })
  })
  .then(() => {
    console.log(1.1) // PROMISE D
    new Promise((resolve => {
        resolve()
      }))
Run Code Online (Sandbox Code Playgroud)

我参加了其中的一部分来解释:

因此,承诺A首先解决。这确保了承诺B将立即解决。这是事情变得复杂的时候:由于承诺B已解决,因此承诺C和D现在都进入了事件循环!为什么?因为Promise A有2个.then子句,所以当第一个结束时-事件循环采用第二个是诺言D。但是第一个.then子句也有.then他自己的一个子句-promise C,它也进入事件循环。

承诺D和C之间没有联系!它们可以以任何顺序执行。保留该逻辑,您将看到其余承诺的工作原理,并且如果尝试在不同的OS上运行它,则由于事件循环的OS的实现方式不同,承诺顺序可能会有所不同。

希望这对您有所了解。

免责声明:我没有JS方面的丰富经验,但是Promise确实吸引了我,因此我对此进行了深入研究。我站在我在这里写的所有内容的背后,但是如果我的解释有任何更正,我很想听听!

编辑

我下面的答案也是正确的,但没有任何解释,因此让我补充一下:当您未在诺言(或.then子句,也返回诺言)中返回任何内容时,它将隐式返回没有价值的已解决诺言。例如,在退出承诺之前,基本上就像在承诺C中添加一个return new Promise.resolve()after console.log。当这样完成时,所有.then在诺言B之后的子句只会在前一个结束后才进入事件循环(例如b结束,所以C进入循环,然后是下一个.then,依此类推),但在其他诺言或.then子句之间(例如承诺D)也可以进入。

但是,当您返回.then链接有子句的promise时,请确保将promise + then的整个块按顺序进入事件循环,因此.then子句也将按照您想要的顺序执行:)

tnx @Eugene Sunic除了!