zhuanghaixin / Interview

8 stars 0 forks source link

Promise 代码执行顺序 #222

Open zhuanghaixin opened 2 years ago

zhuanghaixin commented 2 years ago

题目1

async function foo(){
   console.log( await Promise.resolve('foo'))
}
async function bar(){
   console.log(await 'bar')
}
async function baz(){
   console.log('baz')
}

foo()
bar()
baz()

image await会将结果推到消息队列中,队列就是先进先出,正确顺序 baz,foo,bar

题目2

async function foo() {
  console.log(2);
  await null;
  console.log(4);
}
console.log(1);
foo();
console.log(3);
// 1
// 2
// 3
// 4

image 控制台中输出结果的顺序很好地解释了运行时的工作过程: (1)打印1; (2)调用异步函数foo(); (3)(在foo()中)打印2; (4)(在foo()中)await关键字暂停执行,为立即可用的值null向消息队列中添加一个任务; (5)foo()退出; (6)打印3; (7)同步线程的代码执行完毕; (8)JavaScript运行时从消息队列中取出任务,恢复异步函数执行; (9)(在foo()中)恢复执行,await取得null值(这里并没有使用); (10)(在foo()中)打印4; (11)foo()返回。

题目3

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);

image 运行时会像这样执行上面的例子: (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()返回。

可视化 Event loop

可视化1 可视化2 可视化3

文章

https://dev.to/lydiahallie/javascript-visualized-event-loop-3dif