react navite浏览器 Event Loop 和 Node Event Loop 的区别

如果你说的是 React Native 中的 JS Event LoopNode.js Event Loop,核心区别可以先记成一句话:

React Native:JS Event Loop 主要由 RN 的 JavaScript Runtime + 原生平台调度机制驱动。

Node.js:JS Event Loop 由 Node.js + libuv 驱动,并且有非常明确的多个 Event Loop Phase。


1. 先看整体架构

React Native

复制代码
┌──────────────────────────────┐
│        React Native App      │
│                              │
│  ┌────────────────────────┐  │
│  │ JavaScript Runtime     │  │
│  │ Hermes / JSC            │  │
│  │                        │  │
│  │  JS Call Stack         │  │
│  │  Microtask Queue       │  │
│  │  Timer / Promise ...   │  │
│  └───────────┬────────────┘  │
│              │               │
│       RN JS Event Loop       │
│              │               │
│  ┌───────────▼────────────┐  │
│  │ Native iOS / Android   │  │
│  │                         │  │
│  │ Main/UI Thread          │  │
│  │ Native Modules          │  │
│  │ Network / Timer / etc.  │  │
│  └─────────────────────────┘  │
└──────────────────────────────┘

React Native 的 JS 线程本质上运行的是:

复制代码
JavaScript
   ↓
Hermes / JSC
   ↓
JS Event Loop

但是它不是浏览器 Event Loop 的完整复制品,也不是 Node.js 的 libuv Event Loop。


2. Node.js Event Loop

Node.js 的 Event Loop 可以认为是:

复制代码
              ┌───────────────┐
              │   timers      │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │ pending       │
              │ callbacks     │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │ idle / prepare│
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │     poll      │
              │ I/O callbacks │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │    check      │
              │ setImmediate  │
              └───────┬───────┘
                      ↓
              ┌───────────────┐
              │ close         │
              │ callbacks     │
              └───────────────┘
                      │
                      └──────→ 下一轮

这是 Node 最大的特点。

例如:

复制代码
setTimeout(() => {
  console.log('timeout');
}, 0);

setImmediate(() => {
  console.log('immediate');
});

Node 中两者的执行顺序和当前代码所处的上下文有关

尤其:

复制代码
fs.readFile('test.txt', () => {
  setTimeout(() => {
    console.log('timeout');
  }, 0);

  setImmediate(() => {
    console.log('immediate');
  });
});

这里通常:

复制代码
immediate
timeout

因为 fs callback 在 poll phase 中执行,而 setImmediate 属于 check phase。


3. React Native 没有 Node 那套 Phase

这是非常重要的区别。

你不能把 RN 理解成:

复制代码
timers
 ↓
poll
 ↓
check
 ↓
close

RN 没有 Node.js 的:

复制代码
setImmediate()
process.nextTick()

这种 Node 专属机制。

React Native 的 JS 环境更接近:

复制代码
JS Call Stack
      ↓
执行同步代码
      ↓
Microtask Queue
      ↓
Timers / RN 调度
      ↓
下一次 JS Event Loop

例如:

复制代码
console.log('A');

setTimeout(() => {
  console.log('B');
}, 0);

Promise.resolve().then(() => {
  console.log('C');
});

console.log('D');

基本可以理解成:

复制代码
A
D
C
B

也就是:

复制代码
同步任务
   ↓
Promise Microtask
   ↓
Timer

这点和浏览器非常接近。


4. RN vs 浏览器 vs Node

可以这样记:

Browser React Native Node.js
JS Runtime V8 / SpiderMonkey 等 Hermes / JSC V8
Event Loop 浏览器实现 RN + Runtime Node + libuv
Microtask
Promise
setTimeout
setInterval
requestAnimationFrame
DOM
process.nextTick
setImmediate ❌/不应依赖
libuv
I/O Poll Phase 浏览器内部实现 Native 平台机制 ✅ 明确存在
UI Rendering 浏览器控制 Native UI

所以:

React Native 更接近 Browser Event Loop,而不是 Node Event Loop。

但 RN 又不能简单等同于浏览器,因为 RN 没有 DOM、Rendering Pipeline 也完全不同。


5. React Native 最大的特殊点:JS Thread

RN 开发中 Event Loop 最容易和 JS Thread 搞混。

比如:

复制代码
function heavyTask() {
  for (let i = 0; i < 10000000000; i++) {}
}

heavyTask();

这不是说:

Event Loop 坏了。

而是:

复制代码
JS Thread

┌─────────────────────────────┐
│ heavyTask()                 │
│ ██████████████████████████  │
│                             │
│ Promise callback            │ ← 等待
│ setTimeout callback         │ ← 等待
│ React update                │ ← 等待
└─────────────────────────────┘

JS Call Stack 被长任务占住了。

所以:

复制代码
setTimeout(fn, 0);

并不是:

0ms 后马上执行

而是:

至少等到 timer 到期,并且 JS Thread 有机会执行它。


6. RN 为什么会出现「卡 UI」

这是 RN 和 Node 非常重要的区别。

假设:

复制代码
for (let i = 0; i < 1e10; i++) {}

RN:

复制代码
JS Thread
   │
   │  💥 被占满
   ↓
Event Loop 无法继续
   ↓
JS callbacks 无法执行
   ↓
JS 驱动的 UI 更新无法及时处理
   ↓
用户感觉卡顿

Node:

复制代码
Node JS Thread
   │
   │ heavy computation
   ↓
Event Loop 被阻塞
   ↓
HTTP callbacks
Timer callbacks
I/O callbacks
全部延迟

所以两者有一个共同原则:

JavaScript 是单线程执行的,长时间同步任务都会阻塞 Event Loop。

只是 RN 最终体现为界面交互/动画卡顿 ,Node 更多体现为请求、I/O、Timer 响应变慢


7. Microtask 是两者都非常重要的东西

例如:

复制代码
console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

Promise.resolve().then(() => {
  console.log('3');
});

console.log('4');

RN / Browser 可以理解成:

复制代码
Call Stack

1
4
 ↓
Microtask Queue

3
 ↓
Task / Timer

2

结果:

复制代码
1
4
3
2

Node 也是:

复制代码
1
4
3
2

但 Node 还有一个特殊机制:

复制代码
process.nextTick()

例如:

复制代码
console.log('1');

process.nextTick(() => {
  console.log('2');
});

Promise.resolve().then(() => {
  console.log('3');
});

console.log('4');

Node 中:

复制代码
1
4
2
3

因为:

复制代码
process.nextTick
       ↓
Promise Microtask
       ↓
Event Loop Phase

所以如果你在 RN 代码里看到:

复制代码
process.nextTick(...)

要特别警惕:

这是 Node 思维,不应该把 Node 的 Event Loop 机制直接套到 RN。


8. RN 还有一个非常重要的东西:Frame

RN 做动画时,你经常会遇到:

复制代码
requestAnimationFrame(() => {
  ...
});

它和:

复制代码
setTimeout(fn, 0);

完全不是一回事。

可以粗略理解:

复制代码
              RN / Native UI
                    │
              Frame / VSync
                    │
        ┌───────────┴───────────┐
        ↓                       ↓
     JS Thread              UI Thread
        │                       │
   JS animation             Native rendering

例如:

复制代码
function animate() {
  requestAnimationFrame(() => {
    updateAnimation();
    animate();
  });
}

它的目标是跟随屏幕刷新节奏。

而:

复制代码
setTimeout(updateAnimation, 16);

只是一个 Timer。

因此在 RN 中:

Timer ≠ Frame。

这也是为什么 React Native 动画性能问题不能只用「Event Loop」解释。


9. 新架构下还要考虑 JSI / UI Thread

如果你研究的是现代 React Native(Fabric + TurboModules + JSI),Event Loop 的问题会更加有意思。

传统模型可以简单理解:

复制代码
JS Thread
    │
    │ Bridge
    ↓
Native Thread

而新架构更多是:

复制代码
JS Runtime
   │
   │ JSI
   ↓
C++ / Native
   │
   ├── Fabric
   ├── TurboModules
   └── Native

因此不能再简单理解成:

复制代码
JS Event Loop
     ↓
Bridge Queue
     ↓
Native Event Loop

尤其是 JSI 是同步调用能力,这和传统 Bridge 的异步消息模型区别很大。


10. 最后给你一个最好记的模型

如果你是做 React Native 前端开发,建议脑子里这样记:

Browser

复制代码
JS
 │
 ├── Call Stack
 │
 ├── Microtask Queue
 │
 ├── Task Queue
 │
 └── Rendering

React Native

复制代码
JS Runtime
 │
 ├── Call Stack
 │
 ├── Microtask Queue
 │
 ├── Timer / RN callbacks
 │
 └── Native / UI / Frame

Node.js

复制代码
Node
 │
 ├── Call Stack
 │
 ├── nextTick Queue
 │
 ├── Microtask Queue
 │
 └── libuv Event Loop
       │
       ├── timers
       ├── pending callbacks
       ├── poll
       ├── check
       └── close

一句话总结:

RN 的 Event Loop 重点是「JS Thread + Microtask + Timer + Frame/UI 调度」;Node 的 Event Loop 重点是「V8 + libuv + 多 Phase + I/O」。

如果你正在准备 RN 面试,最值得继续搞懂的是 「Promise → setTimeout → requestAnimationFrame → React setState 在 RN 中到底谁先执行」,这个比单纯背 Event Loop Phase 更实用。

相关推荐
90后的晨仔1 小时前
uni-app 安卓自有证书完全指南
前端
传奇开心果编程10 小时前
【Xilem 0.4 基础语法学与练】第15课:状态管理与 memoize 性能优化
学习·rust·前端框架
CharlesYu0111 小时前
前端性能优化的第一性原理,是不断缩短“用户发起意图 → 获得可用结果”之间的时间
前端
平头哥技术团队11 小时前
Day 21 _ 页内锚点_给每段起个 id,目录写 href=_#id_,点一下页面就滚到那一段
前端·html·html5
子兮曰13 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
人民广场吃泡面13 小时前
什么是AI Agent?它又能给前端带来哪些效率提升?
前端·人工智能
中科三方13 小时前
两家域名注册商资质被ICANN终止:企业域名资产安全再受关注
前端·网络·安全·域名
bug总结13 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app