异步函数何时实际返回挂起的承诺?
我用谷歌搜索了这个问题很多次,但我看到的唯一答案是:
异步函数始终返回承诺
但我在任何地方都找不到任何答案,这实际上是在什么时候发生的。
是在进入异步函数后立即执行,还是在遇到第一个await
关键字时立即执行?
我刚刚写了这段代码:
async function main() {
console.log(true);
let p = await new Promise(r => setTimeout(r, 2000, 100));
return p;
}
async function f() {
inner(await main())
function inner(d) {
console.log(d + 10)
}
console.log('done')
}
f();
最重要的一行是:
inner(await main())
main()
将首先执行,因为函数调用在优先级表中具有较高的优先级,并且异步函数返回承诺时,它将返回挂起的承诺!
但是要返回它,我们必须首先执行main(),因此它进入主执行上下文并看到console.log(true);
现在是main()
返回待定承诺的位置吗?
或者它将记录此情况,然后它将到达await
关键字,此时它将返回挂起的承诺?
如果这是我们的代码怎么办:
async function main() {
(function thatTakes30SecondsToFinish() {
// some time consuming task
}())
let p = await new Promise(r => setTimeout(r, 2000, 100));
return p;
}
在这种情况下,此行inner(await main())
中的main()
是立即返回待定承诺,还是需要30秒才能返回待定承诺?
现在我猜是:
此行inner(await main())
将立即返回挂起的承诺,但main()内的代码将继续执行,直到到达第一个等待关键字,是否正确?
解决方案
异步函数同步运行,直到到达第一个await
(或函数末尾)。然后,它返回一个新的未解析承诺,该承诺将在稍后函数完成执行时得到解析。然后,异步函数的执行将暂停,调用异步函数的代码的同步执行将继续。
此行内部(await main())将立即返回挂起的承诺,但main()内的代码将继续执行,直到到达第一个等待关键字,是否正确?
没有。首先同步执行main()
,直到异步主函数内部的代码达到await
,然后返回承诺,继续执行f
。然后,await
到达f
本身也返回新承诺并停止执行。
语义详情请参见specification。
相关文章