求助求助 :cry:

2023-01-12 15:48:05 +08:00
 bwensun
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 直接进行后面的内容呀

804 次点击
所在节点    问与答
7 条回复
murmur
2023-01-12 16:02:21 +08:00
这种煞笔问题真的坑死不少人

我的建议

( 1 )如果你是为了开发,就认真按照规范,promise 的写法,老老实实按 async 、await 原理去写规范代码
( 2 )如果你搞清楚底层,不要去看任何解释,看了也晕,最靠谱的办法是去 babel 网站,把这个代码翻译到 IE 级别,然后你会看到 generator 的底层实现,把那个代码读一遍就准了
AoEiuV020CN
2023-01-12 16:11:22 +08:00
> 这两个不应该是不确定的关系吗?
都知道不确定了还纠结什么,当然是怎样都合法的了,
murmur
2023-01-12 16:18:35 +08:00
刚才说的不准确,因为 babel 不帮你处理 Promise 的问题,所以你还得找一下 Promise 的 polyfill ,里面有 setTimeout 0 这样的代码,至少这里可以说明可以脚本先结束然后 async 才结束
ysc3839
2023-01-12 16:21:00 +08:00
JavaScript 没有线程概念,js 的 async function 可以看成是回调函数的语法糖(但你不能假定它一定会按照这种规则来执行),在遇到 await 的时候会拆分成多块,那 async2 中没有 await ,就可以认为和普通函数一致,所以 async2 会先输出。
ysc3839
2023-01-12 16:23:03 +08:00
有能力的话,推荐看看 C++20 coroutine 的原理分析,和 js 的 async function 很类似,都是可以看成回调函数的语法糖。
eason1874
2023-01-12 16:32:20 +08:00
async/await 只是异步函数的语法糖,不是说你用了它就能把函数变成异步,async1() 立即执行是符合常理的

这道题考的是为什么 async1() 执行到一半,也就是 await async2() 之后,切到 script end 然后才又回来完成后续的 async1 end

几年前的题目了,你搜索这段代码就能看到解析。我没理解是为什么,记不住答案 🤣
bwensun
2023-01-13 10:22:14 +08:00
谢谢大家 学习了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/908445

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX