事件循环 Event Loop
事件循环 Event Loop
JS 的执行机制(同步任务、异步任务)
JS 是一门单线程语言,单线程就意味着,所有的任务需要排队,前一个任务结束,才会执行下一个任务。这样所导致的问题是:如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的觉。为了解决这个问题,JS 中出现了同步和异步。
同步任务:即主线程上的任务,按照顺序由上⾄下依次执⾏,当前⼀个任务执⾏完毕后,才能执⾏下⼀个任务。
异步任务:不进⼊主线程,⽽是进⼊任务队列的任务,执行完毕之后会产生一个回调函数,并且通知主线程。当主线程上的任务执行完后,就会调取最早通知自己的回调函数,使其进入主线程中执行。
什么是 Event Loop
- 事件循环 Event Loop 又叫事件队列,两者是一个概念
事件循环指的是 js 代码所在运行环境(浏览器、nodejs)编译器的一种解析执行规则。事件循环不属于 js 代码本身的范畴,而是属于 js 编译器的范畴,在 js 中讨论事件循环是没有意义的。换句话说,js 代码可以理解为是一个人在公司中具体做的事情, 而 事件循环 相当于是公司的一种规章制度。 两者不是一个层面的概念。
宏任务与微任务的概念与区别
为了协调任务有条不紊地在主线程上执行,页面进程引入了 消息队列 和 事件循环机制,渲染进程内部也会维护多个消息队列,比如延迟执行队列和普通的消息队列。然后主线程采用一个 for 循环,不断地从这些任务队列中取出任务并执行任务。这些消息队列中的任务就称为 宏任务。
微任务是一个需要异步执行的回调函数,执行时机是在主函数执行结束之后、当前宏任务结束之前。当 JS 执行一段脚本(一个宏任务)的时候,V8 会为其创建一个全局执行上下文,在创建全局执行上下文的同时,V8 引擎也会在内部创建一个 微任务队列。也就是说 每个宏任务都关联了一个微任务队列。
常见的宏任务与微任务分别有哪些
任务(代码) | 宏/微 | 任务环境 |
---|---|---|
事件 | 宏任务 | 浏览器 |
网络请求(Ajax) | 宏任务 | 浏览器 |
setTimeout() | 定时器宏任务 | 浏览器/Node |
fs.readFile() 读取文件 | 宏任务 | Node |
Promise.then() | 微任务 | 浏览器/Node |
async/await | 微任务 | 浏览器/Node |
事件循环 Event Loop 执行机制
- 进入到 script 标签,就进入到了第一次事件循环.
- 遇到同步代码,立即执行
- 遇到宏任务,放入到宏任务队列里.
- 遇到微任务,放入到微任务队列里.
- 执行完所有同步代码
- 执行微任务代码
- 微任务代码执行完毕,本次队列清空
- 寻找下一个宏任务,重复步骤 1
为什么 Js 是单线程?
Js 是单线程,但是浏览器是多线程。单线程是为了避免 UI 操作混乱,所有和 UI 操作相关的开发语言都应该是单线程。
代码题易考点
- promise 本身是一个同步的代码,只有它后面调用的 then()方法里面的回调才是微任务
- then 方法需要 Promise 里的 resolve 传值才会执行
- await 右边的表达式还是会立即执行,表达式之后的代码才是微任务, await 微任务可以转换成等价的 promise 微任务分析
- script 标签本身是一个宏任务, 当页面出现多个 script 标签的时候,浏览器会把 script 标签作为宏任务来解析
个人学习记录所摘,原文作者:逍丶
链接:https://juejin.cn/post/7150861842888261668
来源:稀土掘金