【发布时间】:2019-10-08 00:33:44
【问题描述】:
使用 async/await 函数时调用堆栈的行为如何?
function resolveAfter2Seconds() { // taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
return new Promise(resolve => {
setTimeout(() => {
resolve('resolved');
}, 2000);
});
}
const asyncFuntion=async()=>{
const result = await resolveAfter2Seconds();
console.info("asyncFuntion finish, result is: ", result);
}
const first = async()=>{
await asyncFuntion();
console.log('first completed');
debugger;
}
const second = ()=>{
console.log('second completed');
debugger;
}
function main(){
first();
second();
}
main();
在上面的代码中,当在 second() 中遇到第一个断点时,我可以看到调用堆栈包含 main() 和 second()。在 first() 中的第二个断点期间,调用堆栈包含 main() 和 first()。
在第一个断点期间 first() 发生了什么。推到哪里去了?假设 asyncFunction() 需要一些时间才能完成。
请有人帮忙。
【问题讨论】:
-
将
synchronous和asynchronous函数混合在一起时会出现问题。我不太确定强硬,但我可以想象,main()开始,并将first()推到调用堆栈x,因为它是async。在调用first()之后,立即调用second()并将其推送到不同的调用堆栈,因为sync。我通常把async想象成某种线程。 -
看来你的回答是合乎逻辑的。但是,这与 JS 引擎只有一个调用堆栈这一事实不矛盾吗?
-
是的,
nodes有一个eventloop。但eventloop只是最后的刽子手。我认为仍然会有不同的callstacks或类似队列的东西。最后,事件循环获取所有这些队列并以某种顺序执行它们。我没有足够的知识来正确回答这个问题,所以我只是把它作为评论。 -
是的。我知道事件循环从队列中获取回调并将其推入堆栈。但是,由于使用 await 会阻塞 first() 的执行,所以该函数应该存在于调用堆栈本身中,对吧?
-
我认为,你不能称之为
callstack。我认为这只是堆栈跟踪。我想这是处理得更底层。`
标签: javascript ecmascript-6 promise event-loop