翼度科技»论坛 编程开发 JavaScript 查看内容

第127篇:异步函数(async和await)练习题(异步,消息队列)

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
好家伙,本篇为做题思考
书接上文
 
题目如下:
 1.请给出下列代码的输出结果,并配合"消息队列"写出相关解释
  1. [b]async function foo() {    console.log(2);    console.log(await Promise.resolve(8));    console.log(9);}async function bar() {    console.log(4);    console.log(await 6);    console.log(7);}console.log(1);foo();console.log(3);bar();console.log(5);[/b]
复制代码
 
好我们公布答案:
 
(1) 打印 1;
(2) 调用异步函数 foo();
(3)(在 foo()中)打印 2;
(4)(在 foo()中)await 关键字暂停执行,向消息队列中添加一个期约在落定之后执行的任务;
(5) 期约立即落定,把给 await 提供值的任务添加到消息队列;
(6) foo()退出;
(7) 打印 3;
(8) 调用异步函数 bar();
(9)(在 bar()中)打印 4;
(10)(在 bar()中)await 关键字暂停执行,为立即可用的值 6 向消息队列中添加一个任务;
(11) bar()退出;
(12) 打印 5;
(13) 顶级线程执行完毕;
(14) JavaScript 运行时从消息队列中取出解决 await 期约的处理程序,并将解决的值 8 提供给它;
(15) JavaScript 运行时向消息队列中添加一个恢复执行 foo()函数的任务;
(16) JavaScript 运行时从消息队列中取出恢复执行 bar()的任务及值 6;
(17)(在 bar()中)恢复执行,await 取得值 6;
(18)(在 bar()中)打印 6;
(19)(在 bar()中)打印 7;
(20) bar()返回;
(21) 异步任务完成,JavaScript 从消息队列中取出恢复执行 foo()的任务及值 8;
(22)(在 foo()中)打印 8;
(23)(在 foo()中)打印 9;
(24) foo()返回。
 
所以答案是
1
2
3
4
5
6
7
8
9
 
好了,结束了,没什么问题了
步骤也解释清楚了
 
但是我隐约感到了不对劲
怎么会是123456789呢?
foo()应该是先恢复的,但是这里明显bar()先恢复了
 
 
我们上机试一下

 
 

 
 
诶,结果不对
前面地12345都没有问题,6789的输出变成了8967
我们主要来看和6789有关的输出字段
 
我们再来仔细地看看前面地解释,并把关键解释划出来
(4)(在 foo()中)await 关键字暂停执行,向消息队列中添加一个期约在落定之后执行的任务;
(5) 期约立即落定,把给 await 提供值的任务添加到消息队列;
(6) foo()退出;
 
(10)(在 bar()中)await 关键字暂停执行,为立即可用的值 6 向消息队列中添加一个任务;
(11) bar()退出;
 
(13) 顶级线程执行完毕;
(14) JavaScript 运行时从消息队列中取出解决 await 期约的处理程序,并将解决的值 8 提供给它;
(15) JavaScript 运行时向消息队列中添加一个恢复执行 foo()函数的任务;
(16) JavaScript 运行时从消息队列中取出恢复执行 bar()的任务及值 6;
 
我们回顾一下消息队列
一个 JavaScript 运行时包含了一个待处理消息的消息队列。. 每一个消息都关联着一个用以处理这个消息的回调函数。
再补充一个关于await的知识点
等到 await 右边的值可用了,JavaScript 运行时会向消息 队列中推送一个任务,这个任务会恢复异步函数的执行。
 
我们试着把这个消息队列画出来

 
(有点抽象,但应该能看懂)
这样,我们就会发现, 因为Promise.resolve(8)被多处理了一次,导致了foo()方法后恢复
所以bar()先恢复了
 
那么实际上机又是怎么回事呢?
(书里面有行小字被我忽略了,后面又找到了)

 
 TC39 对 await 后面是期约的情况如何处理做过一次修改。修改后,本例中的 Promise.resolve(8)只会生成一个 异步任务。
因此在新版浏览器中,这个示例的输出结果为 123458967。实际开发中,对于并行的异步操作我们通常 更关注结果,而不依赖执行顺序。——译者注
 
 
实际上机的消息队列

 
原先的两步处理变成了一步
搞定了,原来如此
 

来源:https://www.cnblogs.com/FatTiger4399/p/17198569.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具