开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
主要针对js宏任务和微任务及其执行顺序的理解:
首先是js的执行顺序:
先执行同步代码,遇到异步宏任务则将异步宏任务放入宏任务队列中,遇到异步微任务则将异步微任务放入微任务队列中,当所有同步代码执行完毕后,再将异步微任务从队列中调入主线程执行,微任务执行完毕后再将异步宏任务从队列中调入主线程执行,一直循环直至所有任务执行完毕。
宏任务和微任务分别有哪些?
宏任务:script标签、setTimeout、setInterval、setImmediate、Ajax、DOM事件
微任务:async、await、Promise.then、.finally、.catch
那么宏任务和微任务有什么联系和区别呢?
区别:
宏任务是指不需要立即连贯执行异步任务的
微任务是指需要立即连贯执行异步任务的
联系:
宏任务是主流,当js开始被执行的时候,就是开启一个宏任务,在宏任务中执行一条一条的指令; 宏任务可以同时有多个,但会按顺序一个一个执行; 每一个宏任务,后面都可以跟一个微任务队列,如果微任务队列中有指令或方法,那么就会执行;如果没有,则开始执行下一个宏任务,直到所有的宏任务执行完为止,微任务相当于宏任务的小尾巴;
为什么有了宏任务,还会有微任务存在?
因为宏任务太占用性能,当需要一些较早就准备好的方法,排在最后才执行的时候,又不想新增一个宏任务,那么就可以把这些方法,一个一个的放在微任务队列里面,在这个宏任务中的代码执行完后,就会执行微任务队列。
因此当前同步代码执行,遇到异步任务,如果是异步宏任务,放入下一轮宏任务队列,是异步微任务,放入微任务队列跟在当前宏任务屁股后面。微任务相当于宏任务的小尾巴,
(值得注意的是,这里指的尾巴是第二轮的微任务进入到了第一轮宏任务里,这么说可能会导致误解,但其实只需要记住微任务的执行时间比宏任务早,只不过浏览器解析时会先开启
- 宏任务队列
- 微任务队列
- 调用栈
script标签入宏任务队列,因为script标签前面没有任何微任务 script标签出堆列,押入调用栈)
因此当前宏任务执行完,在它后面等着的异步微任务就会被立刻放入队列继续执行。而异步的宏任务需要等到下一轮,从而造成了异步中微任务在宏任务之前执行的情况。
总结
微任务 > DOM渲染 > 宏任务
stateDiagram-v2
进入任务执行栈--> 判断同步或异步
判断同步或异步 --> 主线程
判断同步或异步 --> 微任务
微任务-->主线程
判断同步或异步 --> 宏任务
宏任务-->主线程
主线程--> [*]