事件循环 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 执行机制

  1. 进入到 script 标签,就进入到了第一次事件循环.
  2. 遇到同步代码,立即执行
  3. 遇到宏任务,放入到宏任务队列里.
  4. 遇到微任务,放入到微任务队列里.
  5. 执行完所有同步代码
  6. 执行微任务代码
  7. 微任务代码执行完毕,本次队列清空
  8. 寻找下一个宏任务,重复步骤 1

为什么 Js 是单线程?

Js 是单线程,但是浏览器是多线程。单线程是为了避免 UI 操作混乱,所有和 UI 操作相关的开发语言都应该是单线程。

代码题易考点

  • promise 本身是一个同步的代码,只有它后面调用的 then()方法里面的回调才是微任务
  • then 方法需要 Promise 里的 resolve 传值才会执行
  • await 右边的表达式还是会立即执行,表达式之后的代码才是微任务, await 微任务可以转换成等价的 promise 微任务分析
  • script 标签本身是一个宏任务, 当页面出现多个 script 标签的时候,浏览器会把 script 标签作为宏任务来解析

个人学习记录所摘,原文作者:逍丶
链接:https://juejin.cn/post/7150861842888261668
来源:稀土掘金