公布答案喽!
首先公布下答案,看看你做对多少嘞?
01
公布答案
第一题:

第二题:

第三题:

你答对了吗?
02
知识储备
宏任务和微任务都包含哪些,如下:
宏任务: script(整体代码), setTimeout, setInterval, setImmediate, I/O(输入输出,比如读取文件操作、网络请求), UI rendering(dom渲染,即更改代码重新渲染dom的过程),异步ajax等;
微任务: Promise(then、catch、finally)、async/await、process.nextTick(Node.js环境,在当前事件循环的末尾执行的回调函数)、Object.observe(⽤来实时监测DOM对象的变化,已废弃)、 MutationObserver(监听DOM树的变化)。
注意:new Promise是同步任务
事件执行顺序:
首先执行当前代码(同步任务),直到遇到第一个宏任务或微任务。
如果遇到微任务,则将它添加到微任务队列中,继续执行同步任务。
如果遇到宏任务,则将它添加到宏任务队列中,继续执行同步任务。
当前任务执行完毕后,JavaScript 引擎会先执行所有微任务队列中的任务,直到微任务队列为空。
然后执行宏任务队列中的第一个任务,直到宏任务队列为空。
重复步骤 4 和步骤 5,直到所有任务都被执行完毕。 需要注意的是,微任务比宏任务优先级要高,因此在同一个任务中,如果既有微任务又有宏任务,那么微任务会先执行完毕。但具体问题还需具体分析。
在一些特殊情况下,微任务和宏任务的执行顺序可能会发生变化,比如在使用 MutationObserver 监听 DOM 变化时,它会被视为一个微任务,但是它的执行顺序可能会比其他微任务更靠后。
宏任务之间的执行顺序是:
setImmediate --> setTimeout --> setInterval --> i/o操作 --> 异步ajax
setImmediate没有时间参数,它与延迟 0 毫秒的 setTimeout() 回调⾮常相似。所以当setTimeout延迟时间也是0毫秒时,谁在前面就先执行谁。此外如果setTimeout延迟时间不是0毫秒,它的执行顺序会在 i/o 操作之后。
微任务之间执行的先后顺序是:
process.nextTick --> Promise
03
解题
第一题:
1.函数定义,先跳过;
2.遇到setTimeout宏任务,放入宏任务队列中,命名为time1;
3.遇到setTimeout宏任务,放入宏任务队列中,命名为time2;
4.执行Promise;
5.Promise.then,放入微任务队列中,命名为then1;
6.执行Promise;
7.Promise.then,放入微任务队列中,命名为then2;
8.执行Promise;
9.Promise.then,放入微任务队列中,命名为then3;
9.执行Promise;
10.Promise.then,放入微任务队列中,命名为then4;
11.执行fn函数,输出y,执行Promise.solve;
12.遇await,将其放入微任务队列,命名为await1;
13.回到主线程,输出0;
14.根据先进先出规则,从微任务队列取出任务 then1 到主线程中,输出5;
15.从微任务队列取出任务 then2 到主线程中,输出6;
16.从微任务队列取出任务 then3 到主线程中,输出7;
17.从微任务队列取出任务 then4 到主线程中,输出8;
18.从微任务队列取出任务 await1 到主线程中,输出x,⾄此微任务队列为空;
19.从宏任务队列中取出 time1,输出1,执行Promise.resole;
20.遇Promise.then,放入微任务队列,命名为then5;
21.从微任务队列取出任务 then5 到主线程中,输出2;
22.从宏任务队列中取出 time2,输出3,执行Promise.resole;
23.遇Promise.then,放入微任务队列,命名为then6;
24.从微任务队列取出任务 then6 到主线程中,输出4;
第二题:
1.遇setTimeout,放入宏任务队列,命名为time1;
2.函数命名,忽略;
3.函数命名,忽略;
4.执行async1,输出1;
5.执行async2,输出2,resole();
6.遇Promise.then,将其放入微任务队列,命名为then1;
7.回到主线程,new Promise,输出3,执行resolve;
8.遇Promise.then,将其放入微任务队列,命名为then2;
9.从微任务队列取出任务then1,输出4,并return;
10.从微任务队列取出任务then2,往下执行,输出5;
11.回到async1,遇到await,将其放入微任务队列,命名为await1;
11.从微任务队列取出任务await1,输出6;
12.遇到async1.then,放入微任务队列,命名为then3;
13.将微任务then3取出到主线程中,输出7;
14.从宏任务队列中取出 time1,输出8
第三题:
1.函数命名,忽略;
2.函数命名,忽略;
3.输出 script start;
4.遇setTimout,将其放入宏任务队列,命名time1;
5.执行async1,输出 async1 start;
6.执行async2,输出 async2;
7.回到async1,遇await,将其放入微任务,命名await1;
8.new Promise,输出 promise1;
9.Promise.then,将其放入微任务队列,命名then1;
10.回到主线程,输出 script end;
11.从微任务中取出await1,输出 async1 end;
12.从微任务中取出then1,输出 promise2;
13.从宏任务中取出time1,输出 setTimeout;
04
拓展
看看这两道题你能否答对呢?