写点什么

【Promise 源码学习】第十八篇 - EventLoop 简介

作者:Brave
  • 2021 年 12 月 12 日
  • 本文字数:1169 字

    阅读完需:约 4 分钟

一,前言


上一篇,主要介绍了 async/await 的使用和实现原理,主要涉及以下几个点:


  • async/await 的使用和功能分析;

  • async/await 的实现和原理分析;


本篇,继续介绍浏览器的事件环 EventLoop;


二,EventLoop 简介


EventLoop 是一个执行模型,在浏览器和 Node 中均有不同的实现:

  • 在 Node 中,使用 libuv 库实现 EventLoop;

  • 在浏览器中,由 Html 规范定义了 EventLoop;


在 JavaScript 代码执行的过程中,可能会进行发送请求、开启定时器等异步操作;

EventLoop 事件循环主要就负责完成相关任务的调度工作;比如:面试中经常问到的执行顺序问题;


备注:EventLoop 是前端领域的重要知识点,也是前端面试的核心考察点;


三,宏任务和微任务


在浏览器的事件循环 EventLoop 执行模型中,涉及宏任务和微任务;


常见宏任务:

  • JS 执行栈:js 在执行时就是一个宏任务;

  • 定时器:setTimeout、setInterval;

  • postMessage、MessageChannel;

  • IE 下的 setImmediate 方法;

  • UI 的界面渲染;

  • 事件;

  • Ajax;


常见微任务:

  • promise.then;

  • mutationObserver;


备注:为了方便记忆,可以简单理解为:除以上两种微任务之外,其余均为宏任务;


四,EventLoop 循环机制


浏览器 EventLoop 图示:



重要组成部分:

  1. 左边 - JS 执行线程:用于执行 JS;(JS 代码为栈型结构执行)

  2. 右边 - GUI 线程:用于界面的渲染;

  3. 上边 - 宏任务队列:用于存储运行中产生的宏任务;宏任务队列全局只有一个;

  4. 下边 - 微任务队列:用于存储运行中产生的微任务;宏任务队列每次循环产生一个;


备注:EventLoop 事件触发线程负责不停地轮训事件队列,并逐个取出进行处理;


代码的执行过程


  • 代码执行

JS 代码从上到下执行,当执行到函数时,会创建执行上下文放入 JS 执行栈;

JS 代码中将包含同步代码和异步代码两种;


  • 异步操作-宏任务(浏览器 API)

执行过程中,可能发生异步操作(如:定时器、ajax、事件等);

当异步操作的时间到达或成功时,将会被放入到事件队列中;(在事件队列中维护宏任务)


备注:由于队列具有先进先出的特点,因此可以保证代码的执行顺序;


  • 事件循环线程

事件循环线程,用于不停地轮训扫描事件队列;事件循环线程,将对当前执行栈进行检测:若执行栈为空,将会从件队列中取出一个放入执行


备注:事件循环线程是一个单独的线程,所以并不会阻塞 JS 的执行;


  • 异步操作-微任务( promise )

代码在执行时,还可能产生一些微任务,如 promise;

在微任务中产生的微任务会被放入当前宏任务下的微任务队列中,即会在当前轮次被情况;


备注:每次执行宏任务时,都会单独创建一个微任务队列;


  • GUI 渲染

浏览器渲染的频率是 16.6 ms,所以并不是每次微任务执行完成后都会执行渲染操作;


  • 总结:每次循环一次,都会执行一个宏任务,并清空对应的微任务队列;



五,结尾


本篇,主要介绍了 EventLoop 的执行原理,主要涉及以下几个点:


  • EventLoop 简介;

  • 宏任务和微任务;

  • EventLoop 循环机制


下一篇,待定;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第十八篇 - EventLoop 简介