如果在无限 while 循环中遇到一个空的 Promise,为什么 while 循环会用一个挂起的 Promise 解决?

If an empty Promise is encountered within an infinite while loop, why is the while loop resolved with a pending Promise?

如果我做出了一个从未实现的承诺:

const nothingPromise = new Promise((resolve) => {});

然后我 await 在无限 while 循环中承诺:

async function run() { while (true) { await nothingPromise;}}

附加到函数的任何 then() 函数都不会 运行,但我也没有得到无限循环。我得到一个待定的 Promise。在 Chrome 控制台中:

run().then(() => console.log('then')) Promise {<pending>}

为什么会返回待处理的 Promise?我有一种感觉,它与 ECMAScript 规范的 this part 有关:

The abstract operation LoopContinues takes arguments completion and labelSet and returns a Boolean. It performs the following steps when called:

  1. If completion.[[Type]] is normal, return true.
  2. If completion.[[Type]] is not continue, return false.
  3. If completion.[[Target]] is empty, return true.
  4. If completion.[[Target]] is an element of labelSet, return true.
  5. Return false.

但是不知道await nothingPromise对应的是哪个完成条件。

await 将其所在的函数发送到睡眠状态,直到:

  • 诺言解决
  • 主事件循环是免费的

因此 while 循环开始,promise 被 awaited,调用 run() 的函数收到 run 返回的 promise(这是待定的,因为run 睡着了)并继续。


因为 nothingPromise 永远不会解析,所以 run 函数永远不会唤醒,所以永远不会完成,也永远不会解析它 returns 的承诺。


您找到的规范部分无关紧要,因为 await 在循环的第一次迭代中间发送 run 休眠,因此循环永远不会完成。