Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove the outdated Deduplication section from event-loop-timers-and-nexttick.md #2158

Merged
6 commits merged into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 0 additions & 50 deletions locale/en/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,56 +398,6 @@ To get around this, the `'listening'` event is queued in a `nextTick()`
to allow the script to run to completion. This allows the user to set
any event handlers they want.

### Deduplication

For the `timers` and `check` phases, there is a single transition
between C to JavaScript for multiple immediates and timers. This deduplication
is a form of optimization, which may produce some unexpected side effects.
Take this code snippet as an example:

```js
// dedup.js
const foo = [1, 2];
const bar = ['a', 'b'];

foo.forEach(num => {
setImmediate(() => {
console.log('setImmediate', num);
bar.forEach(char => {
process.nextTick(() => {
console.log('process.nextTick', char);
});
});
});
});
```
```bash
$ node dedup.js
setImmediate 1
setImmediate 2
process.nextTick a
process.nextTick b
process.nextTick a
process.nextTick b
```

The main thread adds two `setImmediate()` events, which when processed
will add two `process.nextTick()` events. When the event loop reaches
the `check` phase, it sees that there are currently two events created by
`setImmediate()`. The first event is grabbed and processed, which prints
and adds two events to the `nextTickQueue`.

Because of deduplication, the event loop does not transition back to the
C/C++ layer to check if there are items in the `nextTickQueue` immediately. It
instead continues to process any remaining `setImmediate()` events, of which
one currently remains. After processing this event, two more events are
added to the `nextTickQueue` for a total of four events.

At this point, all previously added `setImmediate()` events have been processed.
The `nextTickQueue` is now checked, and events are processed in FIFO order. When
this `nextTickQueue` is emptied, the event loop considers all operations to have
been completed for the current phase and transitions to the next phase.

## `process.nextTick()` vs `setImmediate()`

We have two calls that are similar as far as users are concerned, but
Expand Down
11 changes: 7 additions & 4 deletions locale/fa/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ emitted via `process.nextTick()`.
`setImmediate()` and `setTimeout()` are similar, but behave in different
ways depending on when they are called.

* `setImmediate()` is designed to execute a script once the current
**poll** phase completes.
* `setImmediate()` is designed to execute a script once the
current **poll** phase completes.
* `setTimeout()` schedules a script to be run after a minimum threshold
in ms has elapsed.

Expand Down Expand Up @@ -293,8 +293,11 @@ within an I/O cycle, independently of how many timers are present.
You may have noticed that `process.nextTick()` was not displayed in the
diagram, even though it's a part of the asynchronous API. This is because
`process.nextTick()` is not technically part of the event loop. Instead,
the `nextTickQueue` will be processed after the current operation
completes, regardless of the current phase of the event loop.
the `nextTickQueue` will be processed after the current operation is
completed, regardless of the current phase of the event loop. Here,
an *operation* is defined as a transition from the
underlying C/C++ handler, and handling the JavaScript that needs to be
executed.

Looking back at our diagram, any time you call `process.nextTick()` in a
given phase, all callbacks passed to `process.nextTick()` will be
Expand Down
13 changes: 8 additions & 5 deletions locale/it/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,11 +215,11 @@ emitted via `process.nextTick()`.

## `setImmediate()` vs `setTimeout()`

`setImmediate` and `setTimeout()` are similar, but behave in different
`setImmediate()` and `setTimeout()` are similar, but behave in different
ways depending on when they are called.

* `setImmediate()` is designed to execute a script once the current
**poll** phase completes.
* `setImmediate()` is designed to execute a script once the
current **poll** phase completes.
* `setTimeout()` schedules a script to be run after a minimum threshold
in ms has elapsed.

Expand Down Expand Up @@ -293,8 +293,11 @@ within an I/O cycle, independently of how many timers are present.
You may have noticed that `process.nextTick()` was not displayed in the
diagram, even though it's a part of the asynchronous API. This is because
`process.nextTick()` is not technically part of the event loop. Instead,
the `nextTickQueue` will be processed after the current operation
completes, regardless of the current phase of the event loop.
the `nextTickQueue` will be processed after the current operation is
completed, regardless of the current phase of the event loop. Here,
an *operation* is defined as a transition from the
underlying C/C++ handler, and handling the JavaScript that needs to be
executed.

Looking back at our diagram, any time you call `process.nextTick()` in a
given phase, all callbacks passed to `process.nextTick()` will be
Expand Down
11 changes: 7 additions & 4 deletions locale/ja/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ emitted via `process.nextTick()`.
`setImmediate()` and `setTimeout()` are similar, but behave in different
ways depending on when they are called.

* `setImmediate()` is designed to execute a script once the current
**poll** phase completes.
* `setImmediate()` is designed to execute a script once the
current **poll** phase completes.
* `setTimeout()` schedules a script to be run after a minimum threshold
in ms has elapsed.

Expand Down Expand Up @@ -293,8 +293,11 @@ within an I/O cycle, independently of how many timers are present.
You may have noticed that `process.nextTick()` was not displayed in the
diagram, even though it's a part of the asynchronous API. This is because
`process.nextTick()` is not technically part of the event loop. Instead,
the `nextTickQueue` will be processed after the current operation
completes, regardless of the current phase of the event loop.
the `nextTickQueue` will be processed after the current operation is
completed, regardless of the current phase of the event loop. Here,
an *operation* is defined as a transition from the
underlying C/C++ handler, and handling the JavaScript that needs to be
executed.

Looking back at our diagram, any time you call `process.nextTick()` in a
given phase, all callbacks passed to `process.nextTick()` will be
Expand Down
38 changes: 0 additions & 38 deletions locale/zh-cn/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,44 +267,6 @@ server.on('listening', () => {});

为了绕过此现象,`'listening'` 事件在 `nextTick()` 中排队,以允许脚本运行到完成阶段。这允许用户设置所需的任何事件处理程序。

### 去重

对于 `timers` 以及 `check` 两个阶段而言,多个 immediates 和 timers 中存在着单一的从 C 到 JavaScript 的转变。此去重是一种优化形式,可能会造成一些意想不到的副作用。

我们用以下代码举例子说明:

```js
// dedup.js
const foo = [1, 2];
const bar = ['a', 'b'];

foo.forEach(num => {
setImmediate(() => {
console.log('setImmediate', num);
bar.forEach(char => {
process.nextTick(() => {
console.log('process.nextTick', char);
});
});
});
});
```
```bash
$ node dedup.js
setImmediate 1
setImmediate 2
process.nextTick a
process.nextTick b
process.nextTick a
process.nextTick b
```

主线程添加了两个 `setImmediate()` 事件,这样的话在处理的时候就会增加两个 `process.nextTick()` 事件。当事件轮询到 `check` 阶段的时候,它就发现目前有两个由 `setImmediate()` 创建的两个事件,第一个事件就被立即抓取且得到了处理,这样就打印出相应的结果,并且添加了两个事件到 `nextTickQueue` 队列中。

因为去重的缘故,事件循环机制并不会立即折回到 C/C++ 层面上去检查 `nextTickQueue` 队列中是否存在任务项需要执行;相反地,它只会执行剩余的 `setImmediate()` 事件(目前只剩下一个)。这样一来,在处理了这个事件之后,多余两个的事件添加到了 `nextTickQueue` 队列中,所以总共产生了四个事件。

此时,先前所有的 `setImmediate()` 事件已被处理。终于等到 `nextTickQueue` 队列接受检查,而事件又是按着先进先出的顺序进行处理;因此当 `nextTickQueue` 清空之时,事件循环机制认为所有的操作对于现阶段均已完成,然后直接进行下一个阶段的处理了。

## `process.nextTick()` 对比 `setImmediate()`

就用户而言我们有两个类似的调用,但它们的名称令人费解。
Expand Down