Skip to content

Commit 0ec4f12

Browse files
committed
Updates basic/nextTick-setTimeout.md
Auto commit by GitBook Editor
1 parent 78d23da commit 0ec4f12

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

basic/nextTick-setTimeout.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
## 理解setTimeout、setImmediate、process.nextTick的区别
22

3+
![](/image/1-12-4.jpg)
4+
35
1. `setTimeout` 注册的回调会在事件循环的 `timers``poll`` closing callbacks `阶段执行。需要注意的是,计时器默认定义的 TIMEOUT_MAX 的取值范围是 `[1, 2 ^ 31 - 1]`,不足 1 或者超过上限都会初始化为 1,也就是说你调用 `setTimeout(fn, 0) ``setTimeout(fn, 1) `的效果是一样的。另一点,当timer到延时处理方法到达触发条件,于是将延时处理方法加入**任务队列**,必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。没有办法保证,回调函数一定会在setTimeout()指定的时间执行。(setInterval会不管回调,准时调用)
46

57
2. `process.nextTick` 方法可以在当前"执行栈"的尾部-->下一次Event Loop(主线程读取"任务队列")之前-->触发。process指定的回调函数注册的回调会在事件循环的当前阶段结束前执行,而不是只有 `poll``check` 阶段才会执行。`process` 是内核模块,运行时是全局上下文,所以 `microtask` 只有一个,无论你是在哪个阶段、哪个闭包内用 `nextTick` 注册的回调都会被 `push``nextTickQueue`,并在事件循环当前阶段结束前执行。
68

79
3. `setImmediate` 注册的回调会在 `check` 阶段执行,属于check观察者,其设置的回调函数,会插入到**下次事件循环的末尾**。。因为它需要由 `check watcher `来执行,`check watcher `只在` check `阶段处于 `active` 状态。与 `process.nextTick `不同,setImmediate 因运行时的上下文不同而产生不同的 `ImmediateList`,所以 `microtask `可以有多个。`setImmediate` 会在异常的时候执行` process.nextTick(processImmediate)`,会在当前阶段结束前重新执行一次这个异常任务(即 check 阶段)。Else,创建异步操作的话毋庸置疑是使用setImmediate。
810

11+
4. setImmediate和setTimeout,似乎这两者执行顺序是不确定的
12+
13+
参考 Issuses-6034,Node.js核心作者TJ的解释:
14+
15+
```
16+
timers are based on a time in the future, even if it’s 0, while check immediate is always on the next turn of the loop. So it’s possible that the delay of the event loop is low enough for the timer to fire after the immediate.
17+
18+
You shouldn’t necessarily be concerned about the order of operations in this regard though in my estimation.
19+
```
20+
921

1022
### 举例
1123

0 commit comments

Comments
 (0)