前端那些事

vuePress-theme-reco chenpeng    2020 - 2021
前端那些事 前端那些事

Choose mode

  • dark
  • auto
  • light
首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
author-avatar

chenpeng

85

Article

25

Tag

首页
文章目录
  • Browser
  • CSS
  • ES6
  • JavaScript
  • Network
  • TypeScript
  • Vue
  • Vue3
  • Webpack
标签
时间轴
GitHub
  • JS-V8引擎原理

    • 宏任务与微任务、Event Loop事件循环
    • JS的垃圾回收机制
    • setTimeout与setInterval

宏任务与微任务、Event Loop事件循环

vuePress-theme-reco chenpeng    2020 - 2021

宏任务与微任务、Event Loop事件循环

chenpeng 2020-11-30 JS引擎

JS 语言的一大特点就是单线程,所有任务都在主线程上运行,,也就是说,同一个时间只能做一件事。为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为,就出现了 Event Loop。

# 1.Event Loop执行任务流程

19025755-fff334d16d186d2c
  • 同步和异步任务分别进入不同的执行场所,同步任务进入主线程,异步任务进去 Event Table 并注册函数
  • 注册回调函数后,Event Table 会将任务移入 Event Queue
  • 主线程内的同步任务执行完毕后,会去 Event Queue 读取异步任务,进入主线程执行
  • 上述过程会不断重复,也就是 Event Loop

# 2.宏任务与微任务

宏任务:

  • script(整体代码)
  • setTimeout
  • setInterval
  • I/O
  • requestAnimationFrame(浏览器环境)
  • postMessage
  • MessageChannel
  • setImmediate(Nodejs 环境)

微任务:

  • Promise.then
  • queueMicrotask
  • Object.observe(已废弃)
  • MutationObserver(html5新特性)
  • process.nextTick(Nodejs 环境)

# 3.宏任务与微任务的执行过程

  1. 执行一个宏任务(执行栈中没有就从事件队列中获取)(同步任务也属于宏任务)
  2. 执行过程中如果遇到微任务,就将它添加到微任务队列中
  3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  4. 当前宏任务执行完毕,开始检查渲染,然后 GUI 线程接管渲染
  5. 渲染完毕后,JS 线程继续接管,开始下一个宏任务(从事件队列中获取)
v2-e6dd78c74cb671dd9408c2273308a265_720w

# 4.Node.js 中的事件循环

   ┌───────────────────────────┐
┌─>│           timers         │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │     pending callbacks     │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
│  │       idle, prepare       │
│  └─────────────┬─────────────┘      ┌───────────────┐
│  ┌─────────────┴─────────────┐      │   incoming:   │
│  │           poll            │<─────┤  connections, │
│  └─────────────┬─────────────┘      │   data, etc.  │
│  ┌─────────────┴─────────────┐      └───────────────┘
│  │           check           │
│  └─────────────┬─────────────┘
│  ┌─────────────┴─────────────┐
└──┤      close callbacks     │
   └───────────────────────────┘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  • timers: 计时器阶段,用于处理 setTimeout 以及 setInterval 的回调函数
  • pending callbacks: 用于执行某些系统操作的回调,例如TCP错误
  • idle, prepare: Node内部使用,不用做过多的了解
  • poll: 轮询阶段,执行队列中的 I/O 队列,并检查定时器是否到时
  • check: 执行 setImmediate 的回调
  • close callbacks: 处理关闭的回调,例如 socket.destroy()

process.nextTick 是Node.js中一个特殊的微任务,因此会为它单独提供一个队列,称为 next tick queue,并且其优先级大于其它的微任务,即若同时存在 process.nextTick 和 promise,则会先执行前者