async function async1(){
console.log('async1 start');
await async2();
console.log('async1 end')
}
async function async2(){
console.log('async2')
}
console.log('script start');
async1();
console.log('script end')
输出顺序:script start->async1 start->async2->script end->async1 end
问:为什么'async2'的输出在'script end'的前面,这两个不应该是不确定的关系吗?线程遇到 await 直接进行后面的内容呀
1
murmur 2023-01-12 16:02:21 +08:00
这种煞笔问题真的坑死不少人
我的建议 ( 1 )如果你是为了开发,就认真按照规范,promise 的写法,老老实实按 async 、await 原理去写规范代码 ( 2 )如果你搞清楚底层,不要去看任何解释,看了也晕,最靠谱的办法是去 babel 网站,把这个代码翻译到 IE 级别,然后你会看到 generator 的底层实现,把那个代码读一遍就准了 |
2
AoEiuV020CN 2023-01-12 16:11:22 +08:00
> 这两个不应该是不确定的关系吗?
都知道不确定了还纠结什么,当然是怎样都合法的了, |
3
murmur 2023-01-12 16:18:35 +08:00
刚才说的不准确,因为 babel 不帮你处理 Promise 的问题,所以你还得找一下 Promise 的 polyfill ,里面有 setTimeout 0 这样的代码,至少这里可以说明可以脚本先结束然后 async 才结束
|
4
ysc3839 2023-01-12 16:21:00 +08:00 via Android
JavaScript 没有线程概念,js 的 async function 可以看成是回调函数的语法糖(但你不能假定它一定会按照这种规则来执行),在遇到 await 的时候会拆分成多块,那 async2 中没有 await ,就可以认为和普通函数一致,所以 async2 会先输出。
|
5
ysc3839 2023-01-12 16:23:03 +08:00 via Android
有能力的话,推荐看看 C++20 coroutine 的原理分析,和 js 的 async function 很类似,都是可以看成回调函数的语法糖。
|
6
eason1874 2023-01-12 16:32:20 +08:00
async/await 只是异步函数的语法糖,不是说你用了它就能把函数变成异步,async1() 立即执行是符合常理的
这道题考的是为什么 async1() 执行到一半,也就是 await async2() 之后,切到 script end 然后才又回来完成后续的 async1 end 几年前的题目了,你搜索这段代码就能看到解析。我没理解是为什么,记不住答案 🤣 |
7
bwensun OP 谢谢大家 学习了
|