欢迎光临散文网 会员登陆 & 注册

公布答案喽!

2023-09-05 13:00 作者:bengdour  | 我要投稿

首先公布下答案,看看你做对多少嘞?



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是同步任务


事件执行顺序:

  1. 首先执行当前代码(同步任务),直到遇到第一个宏任务或微任务。

  2. 如果遇到微任务,则将它添加到微任务队列中,继续执行同步任务。

  3. 如果遇到宏任务,则将它添加到宏任务队列中,继续执行同步任务。

  4. 当前任务执行完毕后,JavaScript 引擎会先执行所有微任务队列中的任务,直到微任务队列为空。

  5. 然后执行宏任务队列中的第一个任务,直到宏任务队列为空。

  6. 重复步骤 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

拓展

看看这两道题你能否答对呢?





公布答案喽!的评论 (共 条)

分享到微博请遵守国家法律