一.前言
js是单线程语言,多个任务执行的时候,页面就会阻塞。为了解决这个问题,就出现了同步任务和异步任务。
二.什么是同步任务、异步任务?
同步任务:即主线程的任务,按照顺序由上到下依次执行,当一个任务执行完了,才能执行下一个任务。
异步任务:不进入主线程,而是进入任务队列的任务,执行完毕后会生成一个回调函数,并且通知主线程。
当主线程执行完毕后,就会调取最早通知自己的回调函数,进入主线程中执行。异步任务分为宏任务和微任务。
像网络请求任务。
三.宏任务和微任务是什么?
宏任务:setTimeout、setInterval、ajax、DOM事件
微任务:promise、async/await、process.nextTick(node独有)
四.宏任务和微任务怎么执行的?
执行顺序:主线程>> 主线程上创建的微任务>>主线程上创建的宏任务
1.进入到script标签,就进入第一次事件循环
2.遇到同步任务,立即执行。
3.执行过程中遇到宏任务,添加到宏任务中
4.执行过程中遇到微任务,添加到微任务队列中。
5.执行完所有同步任务。
6.微任务执行完毕后,执行下一个宏任务。
7.当前宏任务执行完毕后,立即执行当前微任务队列中的所有微任务。
五.案例
1.案例1
(1)先执行同步任务,打印1
(2)Promise本身是一个同步的代码,只有它后面的then()方法里面的回调才是微任务。打印3
(3)执行同步任务,打印5
(4)同步任务执行完,调取微任务队列,执行then中回调函数,打印4
(5)当前的微任务执行完之后,执行宏任务setTimeout,打印2
2.案例2
(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'