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



如果我许下了一个永远不会实现的承诺:

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

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

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

任何附加到函数的then()函数都不会运行,但我也不会得到无限循环。我得到一个未决的承诺。在Chrome控制台:

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

为什么要返回一个未完成的承诺?我有一种感觉,它与ECMAScript规范的这一部分有关:

抽象操作loopcontinuations接受参数completion和labelSet,并返回一个布尔值。它在调用时执行以下步骤:

  1. 如果完成。[[Type]]为normal,返回true。
  2. 如果完成。[[类型]]没有继续,返回false。
  3. 如果完成。[[Target]]为空,返回true。
  4. 如果完成。[[Target]]是labelSet的一个元素,返回true。
  5. 返回false。

但是我不知道哪个完成条件对应于await nothingPromise

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

  • 承诺解析
  • 主事件循环空闲

因此,while循环开始,承诺是await的,调用run()的函数接收run返回的承诺(由于run处于休眠状态,因此正在挂起)并继续。


由于nothingPromise永远不会解析,因此run函数永远不会唤醒,因此永远不会完成,并且永远不会解析它返回的承诺。


您发现的规范部分是不相关的,因为await在循环的第一次迭代中间将run发送到睡眠状态,因此循环从未完成。

最新更新