关于async/await执行顺序的困惑:无异步操作为何执行顺序不符预期
无异步操作的async函数为何会改变执行顺序?
async function f1() { console.log('this is f1'); let res = await f3(); console.log('result of f1 from f3 = ', res['status']); console.log('end of f1'); } async function f3() { console.log('this is f3') console.log('returning res from f3'); return {"status": 600} ; } f1(); console.log('inside global context');
1. 为什么先打印inside global context?
这是await的核心机制决定的:只要遇到await,不管右侧表达式返回的是已决议Promise还是普通值,JavaScript都会把当前函数的后续代码放到「微任务队列」中,然后立即让出执行权,让当前调用栈里的同步代码先执行完。
具体执行流程:
- 调用
f1(),进入f1同步执行console.log('this is f1') - 执行
await f3(),先同步调用f3:执行f3里的两个console.log,然后f3返回结果 - 此时
await触发:把f1中await之后的两行console.log加入微任务队列,暂停f1并将其从调用栈移除 - 调用栈回到全局上下文,执行
console.log('inside global context') - 全局同步代码执行完毕后,JavaScript处理微任务队列,执行
f1剩余代码
2. f3究竟返回了什么?为什么f1没有立即使用它?
所有async函数的返回值都会被自动包装成已决议的Promise,哪怕return的是普通对象、字符串或数字。这里f3返回的{"status":600}会被包装成Promise.resolve({"status":600})。
至于f1没有立即使用这个值,是因为await的规则:不管Promise是否已resolved,await都会强制让出执行权,等当前调用栈清空后再处理后续逻辑——这是语言设计的一致性要求,保证不管右侧是同步还是异步Promise,await行为统一。
3. f3返回JSON时f1仍在调用栈中吗?
不正确。当f3执行到return语句时,f3已执行完毕并退出调用栈;回到f1的await行后,await会暂停f1,并将f1也从调用栈中移除。此时调用栈里只有全局上下文,接下来才会执行全局的console.log('inside global context')。
内容的提问来源于stack exchange,提问作者Tony Stark
相关产品推荐
相关产品推荐

