JS是单线程的运行机制; js的程序代码可以分为同步任务和异步任务,对于同步的任务,当然按照顺序执行,但是对于异步的操作,会有一个优先级的执行顺序,分别为宏任务和微任务
1 宏任务有哪些
宏任务本质:参与了事件循环的任务;即会被添加到任务队列
2 微任务有哪些
微任务本质:直接在 Javascript 引擎中的执行的,没有参与事件循环的任务。当成普通的回调理解即可
3 根据代码分析
任务队列是一种数据结构,可以存放要执行的任务。它符合队列“先进先出”的特点,也就是说要添加任务的话,添加到队列的尾部;要取出任务的话,从队列头部去取。
如上输出结果会是什么呢?
让我们分析一下
首先明确并列层面的执行顺序:同步主线程->微任务->宏任务
可以看到有并列的四个任务:
1 宏任务, 直接加到任务队列,先不执行
2 同步主线程,直接执行;输出 “2”
3 微任务,先不执行,因为后面有一个同步主线程
4 同步主线程,直接执行;输出 "4"
然后执行第三步的微任务(当成回调理解,不会像宏任务被添加到异步任务队列);输出"3",
最后将任务队列中的宏任务拿出来执行;输出"1"
所以准确结果是:2 4 3 1
4 再看一个例子
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