事件循环在Node.js和浏览器环境下的差异

548 阅读1分钟

概述

不论在浏览器环境,还是Node环境,js运行的事件循环都是重中之重,但两个环境下的事件循环是基于不同的原理,尤其是Node.js 10+版本之前,一个是基于浏览器,一个是基于 libuv 库

V8引擎本身并没有异步运行的能力,而是借助浏览器的其他线程实现的,而在 Node.js 中,异步实现主要依赖于 libuv。

事件循环

事件循环是一个无限while-true循环。

六个阶段

事件循环分为六个阶段:

  1. timers:执行setTimout和setInterval的回调函数;
  2. pending callbacks :执行某些系统操作(如 TCP 错误类型)的回调函数;
  3. prepare: 系统内部使用;
  4. poll: 执行与 I/O 相关的回调,Node可能在这个阶段阻塞。所有的事件循环以及回调处理都在这执行;
  5. check:setImmediate() 回调在这执行。setImmediate 并不是立马执行,而是当 poll 中没有新的事件处理时就执行该部分;

发起事件循环

当 Node.js 启动后,会初始化事件循环,处理已提供的输入脚本,它可能会先调用一些异步的 API、调度定时器,或者 process.nextTick(),然后再开始处理事件循环。

所以,Node.js 事件循环的发起点有 4 个:

  1. Node.js 启动后;
  2. setTimeout 回调函数;
  3. setInterval 回调函数;
  4. 也可能是一次 I/O 后的回调函数。

执行流程

image.png