宏任务和微任务的理解

69 阅读2分钟

一.前言

js是单线程语言,多个任务执行的时候,页面就会阻塞。为了解决这个问题,就出现了同步任务和异步任务。

二.什么是同步任务、异步任务?

同步任务:即主线程的任务,按照顺序由上到下依次执行,当一个任务执行完了,才能执行下一个任务。

异步任务:不进入主线程,而是进入任务队列的任务,执行完毕后会生成一个回调函数,并且通知主线程。

当主线程执行完毕后,就会调取最早通知自己的回调函数,进入主线程中执行。异步任务分为宏任务和微任务。

像网络请求任务。

三.宏任务和微任务是什么?

宏任务:setTimeout、setInterval、ajax、DOM事件

微任务:promise、async/await、process.nextTick(node独有)

四.宏任务和微任务怎么执行的?

执行顺序:主线程>> 主线程上创建的微任务>>主线程上创建的宏任务

image-20231110174036783.png

1.进入到script标签,就进入第一次事件循环

2.遇到同步任务,立即执行。

3.执行过程中遇到宏任务,添加到宏任务中

4.执行过程中遇到微任务,添加到微任务队列中。

5.执行完所有同步任务。

6.微任务执行完毕后,执行下一个宏任务。

7.当前宏任务执行完毕后,立即执行当前微任务队列中的所有微任务。

五.案例

1.案例1

image-20231113161412841.png

(1)先执行同步任务,打印1

(2)Promise本身是一个同步的代码,只有它后面的then()方法里面的回调才是微任务。打印3

(3)执行同步任务,打印5

(4)同步任务执行完,调取微任务队列,执行then中回调函数,打印4

(5)当前的微任务执行完之后,执行宏任务setTimeout,打印2

2.案例2

image-20231113161130148.png

(1)同步任务执行,打印'script start'

(2)执行函数async1,进入async1内部,async1起始是声明了一个promise, promise是同步代码,会按顺序执行打印async2函数里面的'async2',只有.then里面的代码会添加到微任务队列,这里相当于执行了async2()之后,再将后面的代码加入微任务队列中。

(3)执行promise同步代码,.then后面的回调函数添加到微任务队列中, 打印'promise1'

(4)同步任务,打印'script end'

(5)执行完所有同步任务,执行微任务队列,打印'async1 end'

(6)继续查找当前微任务队列,打印'promise2'

(7)继续查找当前微任务队列,没有,开始执行宏任务,打印'setTimeout'