分析异步操作中的宏任务(macrotasks)与微任务(microtasks)

已被阅读 714 次 | 文章分类:javascript | 2022-01-29 18:24

JS是单线程的运行机制; js的程序代码可以分为同步任务和异步任务,对于同步的任务,当然按照顺序执行,但是对于异步的操作,会有一个优先级的执行顺序,分别为宏任务和微任务

1 宏任务有哪些

宏任务本质:参与了事件循环的任务;即会被添加到任务队列;宏任务有以下几种:

/net/upload/image/20220129/5f2335d0-e1ad-4d1b-a7ba-edd7f6732e68.png

2 微任务有哪些

微任务本质:直接在 Javascript 引擎中的执行的,没有参与事件循环的任务。当成普通的回调理解即可

/net/upload/image/20220129/ca41bab0-4d27-4900-be38-26884e825e18.png

3 代码验证

任务队列是一种数据结构,可以存放要执行的任务。它符合队列“先进先出”的特点,也就是说要添加任务的话,添加到队列的尾部;要取出任务的话,从队列头部去取

如下是一个例子

/net/upload/image/20220129/ad1cafd84ea14d3dae62d01f202b64ed.png

如上输出结果会是什么呢?让我们分析一下

首先明确并列层面的执行顺序:同步主线程->微任务->宏任务

可以看到有并列的四个任务:

                                            
1 宏任务, 直接加到任务队列,先不执行

2 同步主线程,直接执行;输出 “2”

3 微任务,先不执行,因为后面有一个同步主线程

4 同步主线程,直接执行;输出 "4"

然后执行第三步的微任务(当成回调理解,不会像宏任务被添加到异步任务队列);输出"3",

最后将任务队列中的宏任务拿出来执行;输出"1"
                                            
                                        

所以准确结果是:2 4 3 1

4 再看一个例子

/net/upload/image/20220129/c95d1b5fc57d41b196947f25fb4406a3.png

                                            
1 宏任务;直接扔到任务队列等着;

2 同步主线程;直接执行;输出 "2" ;

3 微任务;先暂时挂起来;因为是promise的回调嘛

4 同步主线程;直接执行;输出"4"

     (1) 然后执行第三步的微任务的回调结果;输出"3"

     (2) 没有其他主线程或者微任务后;将异步队列中的任务,从头到尾拿到主线程执行;把宏任务1里面的程序展开到主线程中开始执行;

5 同步主线程;直接执行;输出"1"

6 宏任务;直接扔到任务队列等着;

7 同步主线程;直接执行;输出 "6";

8 微任务;先暂时挂起来;因为是promise的回调嘛;

后面没有主程序的任务了;所以继续如下:

    (1) 执行挂起来的微任务,里面是同步主线程,输出"7"

    (2) 微任务也没有了,从异步队列中拿出放进去的第5步的宏任务

    (3) 里面是同步主线程,直接执行;输出"5"
                                            
                                        

结果是 2 4 3 1 6 7 5

/net/upload/image/20220129/6efa2bdd86a04ff59930f4ed85878428.png

纸上得来终觉浅,绝知此事要躬行;建议大家可以写一个宏任务、微任务和同步线程复杂嵌套的例子,测试一下;

QQ:3410192267 | 技术支持 微信:popstarqqsmall

Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号