如果我许下了一个永远不会实现的承诺:
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,并返回一个布尔值。它在调用时执行以下步骤:
- 如果完成。[[Type]]为normal,返回true。
- 如果完成。[[类型]]没有继续,返回false。
- 如果完成。[[Target]]为空,返回true。
- 如果完成。[[Target]]是labelSet的一个元素,返回true。
- 返回false。
但是我不知道哪个完成条件对应于await nothingPromise
。
await
将它所在的函数发送到睡眠状态,直到:
- 承诺解析和
- 主事件循环空闲
因此,while
循环开始,承诺是await
的,调用run()
的函数接收run
返回的承诺(由于run
处于休眠状态,因此正在挂起)并继续。
由于nothingPromise
永远不会解析,因此run
函数永远不会唤醒,因此永远不会完成,并且永远不会解析它返回的承诺。
您发现的规范部分是不相关的,因为await
在循环的第一次迭代中间将run
发送到睡眠状态,因此循环从未完成。