首页 > 专栏 > 前端 > 文章详情
理解:JS 的事件循环机制 Event Loop,微任务与宏任务 发布于:2023-02-07 13:59:34   来源:   查看:182  讨论:0

0.前言

yyT易塔云建站-模板下载,web开发资源,技术博客
JS是一门单线程语言,单线程意味着,所有的任务都需要排队,前一个任务结束,才会执行下一个任务。yyT易塔云建站-模板下载,web开发资源,技术博客
这样所导致的问题:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面的渲染阻塞。yyT易塔云建站-模板下载,web开发资源,技术博客
为了解决这个问题,JS中出现了同步和异步。yyT易塔云建站-模板下载,web开发资源,技术博客
他们的本质区别:一条流水线上各个流程的执行顺序不同。yyT易塔云建站-模板下载,web开发资源,技术博客
首先先了解一下同步任务与异步任务。yyT易塔云建站-模板下载,web开发资源,技术博客
同步任务:即主线程上的任务,按照顺序由上至下依次执行,当前一个任务执行完毕后,才能执行下一个任务。yyT易塔云建站-模板下载,web开发资源,技术博客
异步任务:不进入主线程,而是进入任务队列,执行完毕之后会产生一个回调函数,并且通知主线程。当主线程的实时任务执行完成后,就会调取最早通知自己的回调函数,使其进入主线程中执行。
yyT易塔云建站-模板下载,web开发资源,技术博客
 

1. 事件循环Event Loop概念介绍

yyT易塔云建站-模板下载,web开发资源,技术博客
事件循环 Event Loop 又叫事件队列,两者是一个概念。yyT易塔云建站-模板下载,web开发资源,技术博客
事件循环指的是 js 代码所在运行环境(浏览器,nodeJS)编译器的一种解析执行规则。yyT易塔云建站-模板下载,web开发资源,技术博客
事件循环不属于 js 代码本身的范畴,而是属于 js 编译器的范畴,在 js 中讨论事件循环是没有意义的。yyT易塔云建站-模板下载,web开发资源,技术博客
换句话说,js 代码可以理解为是一个人在公司中具体做的事情,而事件循环 相当于是 公司的一种规章制度。yyT易塔云建站-模板下载,web开发资源,技术博客
两者不是一个层面的东西。
yyT易塔云建站-模板下载,web开发资源,技术博客
 

2. 微任务、宏任务概念介绍

 
①. 微任务与宏任务就属于 js 代码的范畴。yyT易塔云建站-模板下载,web开发资源,技术博客
②. js 代码主要分为两大类:同步代码、异步代码。yyT易塔云建站-模板下载,web开发资源,技术博客
③. 异步代码又分为:微任务、宏任务。
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
 

3.Event Loop

①. 进入到 script 标签,就进入到了第一次事件循环。yyT易塔云建站-模板下载,web开发资源,技术博客
②. 遇到同步代码,立即执行yyT易塔云建站-模板下载,web开发资源,技术博客
③. 遇到宏任务,放入宏任务队列里yyT易塔云建站-模板下载,web开发资源,技术博客
④. 遇到微任务,放入微任务队列里yyT易塔云建站-模板下载,web开发资源,技术博客
⑤. 执行完所有不同代码yyT易塔云建站-模板下载,web开发资源,技术博客
⑥. 执行微任务代码yyT易塔云建站-模板下载,web开发资源,技术博客
⑦. 微任务代码执行完毕,本次队列清空yyT易塔云建站-模板下载,web开发资源,技术博客
⑧. 寻找下一个宏任务,重复步骤 ①
yyT易塔云建站-模板下载,web开发资源,技术博客
以此反复知道清空所有宏任务,这种不断重复的执行机制,就叫事件循环。yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
 

4.易错点

yyT易塔云建站-模板下载,web开发资源,技术博客
(1). promise本身是一个同步的代码(只是容器),只有它后面调用的then()方法里面的回调才是微任务yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
(2). await右边的表达式还是会立即执行,表达式之后的代码才是微任务,await微任务可以转换成等价的promise微任务分析。yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
(3). script标签本身是一个宏任务,当页面出现多个script标签的时候,浏览器都会把script标签当作宏任务来解析。yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
看到这里,对事件循环应该有所了解了,给大家看几道面试题。yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
一。
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
1.先执行主线程上的log(1)

2.当有两个await时,只有第一个await右边的代码会立即执行log(4),后面的几行代码都会放入微任务队列中。yyT易塔云建站-模板下载,web开发资源,技术博客

3.执行主线程上的log(6)yyT易塔云建站-模板下载,web开发资源,技术博客

4.执行第4行至第6行的微任务yyT易塔云建站-模板下载,web开发资源,技术博客
 yyT易塔云建站-模板下载,web开发资源,技术博客

二。yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
 

1.先执行主线程上的1,5,7yyT易塔云建站-模板下载,web开发资源,技术博客

2.主线程的同步任务执行完毕后,会先执行微任务。执行Promise的then方法里的代码,打印6yyT易塔云建站-模板下载,web开发资源,技术博客

3.微任务执行完毕后,最后执行定时器里的宏任务,注意:setTimeout() 整体被认为一个宏任务代码块。打印2,3,4yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
三。
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
 yyT易塔云建站-模板下载,web开发资源,技术博客

1.先执行主线程上的同步代码,打印1yyT易塔云建站-模板下载,web开发资源,技术博客

2.执行第9行的函数,进⼊async1内部,async1其实是声明了⼀个promise,promise是同步代码,会顺序执⾏打印async2函数里的4 ,只有.then⾥⾯的代码会加⼊微任务队列⾥,这⾥相当于执⾏了async2()之后,再将后面的代码加⼊⼀个微任务队列中。yyT易塔云建站-模板下载,web开发资源,技术博客

3.回主线程中,遇到setTimeout(),加⼊到宏任务队列yyT易塔云建站-模板下载,web开发资源,技术博客

4.主线程继续往后执⾏,前⾯说过,promise是同步代码,.then后⾯的回调会加⼊微任务队列,所以会打印13⾏的7yyT易塔云建站-模板下载,web开发资源,技术博客

5.主线程执⾏完成,开始执⾏微任务队列内的任务,遵循先进先出的原则,打印第四⾏的2。然后接着执行第5行第二个awaite右边的代码,打印5。第6行这个时候就被加入微任务队列。yyT易塔云建站-模板下载,web开发资源,技术博客

6.接着会执行第二个微任务,也就是16行代码,打印8。第17行的then这个时候也会加入微任务队列。再依次执行第6行和第17行的两个微任务,打印3和9yyT易塔云建站-模板下载,web开发资源,技术博客

7.微任务执⾏结束,开始执⾏宏任务setTimeout,打印11⾏的6.yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
再次注释:
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客
yyT易塔云建站-模板下载,web开发资源,技术博客

评论

  • 匿名