事件循环机制:galagame里真是这样子的!

181 阅读4分钟

前言

js引擎真算是galagame男主吧!同步代码和异步代码就像是男主的后宫们,等待着js引擎不断的循环遍历。

016332511f02a13879f883173a0fb639.jpg

js引擎单线程的执行机制

  1. 什么是单线程
    • 好比做人要专一,好比一个人干活,大部分人一次只能全心全意做一件事,这就是单线程最好的理解方式。
  2. 专一的js引擎
    • js引擎在代码的执行过程中是专一的,一次性只能处理一份代码。没有办法同一时刻处理两份代码。

异步的诞生

同步&异步

js引擎执行代码时,只开一个工作线程工作,为提高执行效率执行效率,碰到需要耗时的代码时,v8引擎无需等待,可以将耗时代码放到任务队列中,等不耗时的代码执行完毕后,回头再执行。

  • 而其中:
    • 不耗时的代码,我们称之为同步代码
    • 耗时的代码,我们称之为异步代码

event-loop (事件循环机制)

1. 简单意义上的事件循环过程(仅供初步理解)

简单意义上来讲js代码的执行是不断重复(执行同步代码 =》 执行异步代码)这一过程.

  • 我们都明白,js引擎会先执行同步代码,将耗时的异步代码放入任务队列中,等同步代码执行完毕,再回头执行耗时代码。这就构成了一个事件流,而js代码的执行就好比于不断的重复该过程

简单意义执行流程.png

2. 任务等待队列

  • 异步代码,是我们主观认为下会耗时执行的代码,js引擎会在执行过程中将异步代码单独提走,放到异步任务队列的中等待执行,但是异步代码之间亦有差距。

1765098696459_709AFA42-71FA-4d3f-8E8E-B25BBBA29860.png

3. 宏任务&微任务

按照异步代码的执行时机划分,异步会被放入两种任务队列等待执行,那就是宏任务队列与微任务队列,被放入相应队列的异步代码,我们称之为宏任务与微任务。

  1. 宏任务:等待下一轮循环执行的代码。
    • 比如:setTimeout(),setInterval(),ajax,I/O,UI-rendering页面渲染等
    • 特点:
      • 依赖外部资源 ,比如:setTimeout()依赖外部资源定时器,ajax依赖网络
      • 执行时机:需要等待下一次事件循环才能够被执行。
  2. 微任务:
    • 比如:promise.then(),process.nextTick(),MutationObserver
    • 特点:
      • 不依赖外部资源,比如 promise.then()依赖promise对象状态,这都是js环境自身拥有的资源。
      • 执行时间,本次事件循环同步代码执行完毕后,立马执行

1765099564617_D369754F-0689-4960-AB7E-DC6068CC877E.png

4. 事实意义上的事件循环机制(event - loop)

js代码的执行是不断的重复(从宏任务队列中取出一个宏任务=》执行宏任务内部同步代码=》清空微任务队列)这一过程,我们称之为事件流。

  1. 从宏任务队列中取出宏任务:
    • 一份js代码全局就是一个宏任务
    • 如果宏任务队列为空,则js引擎就陷入等待,直到新的宏任务出现
  2. 执行宏任务内部同步代码:
    • 执行宏任务内部过程中,所有的同步代码直接执行。
    • 异步代码,则被放入相应的(宏任务/ 微任务)等待序列
  3. 清空微任务队列:
    • 同步代码执行完毕后,立马开始执行微任务队列中等待执行的所有异步代码=》执行所有的微任务
    • 如果微任务队列为空,则直接进入下一步。
  4. 重复第一步

events-loop.png