diff --git a/locale/en/docs/guides/event-loop-timers-and-nexttick.md b/locale/en/docs/guides/event-loop-timers-and-nexttick.md index 8157366e61a1..9adb4a75da55 100644 --- a/locale/en/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/en/docs/guides/event-loop-timers-and-nexttick.md @@ -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 diff --git a/locale/fa/docs/guides/event-loop-timers-and-nexttick.md b/locale/fa/docs/guides/event-loop-timers-and-nexttick.md index 13845164568f..9adb4a75da55 100644 --- a/locale/fa/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/fa/docs/guides/event-loop-timers-and-nexttick.md @@ -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. @@ -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 diff --git a/locale/it/docs/guides/event-loop-timers-and-nexttick.md b/locale/it/docs/guides/event-loop-timers-and-nexttick.md index f0896b04ee20..9adb4a75da55 100644 --- a/locale/it/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/it/docs/guides/event-loop-timers-and-nexttick.md @@ -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. @@ -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 diff --git a/locale/ja/docs/guides/event-loop-timers-and-nexttick.md b/locale/ja/docs/guides/event-loop-timers-and-nexttick.md index 13845164568f..9adb4a75da55 100644 --- a/locale/ja/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/ja/docs/guides/event-loop-timers-and-nexttick.md @@ -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. @@ -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 diff --git a/locale/ko/docs/guides/event-loop-timers-and-nexttick.md b/locale/ko/docs/guides/event-loop-timers-and-nexttick.md index a1106c04652d..45879ef58eb4 100644 --- a/locale/ko/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/ko/docs/guides/event-loop-timers-and-nexttick.md @@ -43,24 +43,24 @@ The following diagram shows a simplified overview of the event loop's order of operations. ``` - ┌───────────────────────┐ -┌─>│ timers │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -│ │ pending callbacks │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -│ │ idle, prepare │ -│ └──────────┬────────────┘ ┌───────────────┐ -│ ┌──────────┴────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └──────────┬────────────┘ │ data, etc. │ -│ ┌──────────┴────────────┐ └───────────────┘ -│ │ check │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -└──┤ close callbacks │ - └───────────────────────┘ + ┌───────────────────────────┐ +┌─>│ timers │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +│ │ pending callbacks │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +│ │ idle, prepare │ +│ └─────────────┬─────────────┘ ┌───────────────┐ +│ ┌─────────────┴─────────────┐ │ incoming: │ +│ │ poll │<─────┤ connections, │ +│ └─────────────┬─────────────┘ │ data, etc. │ +│ ┌─────────────┴─────────────┐ └───────────────┘ +│ │ check │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +└──┤ close callbacks │ + └───────────────────────────┘ ``` *note: each box will be referred to as a "phase" of the event loop.* @@ -76,24 +76,24 @@ Node.js를 시작할 때 이벤트 루프를 초기화하고 제공된 입력 아래 다이어그램은 이벤트 루프의 작업 순서의 간단한 개요를 보여줍니다. ``` - ┌───────────────────────┐ -┌─>│ timers │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -│ │ pending callbacks │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -│ │ idle, prepare │ -│ └──────────┬────────────┘ ┌───────────────┐ -│ ┌──────────┴────────────┐ │ incoming: │ -│ │ poll │<─────┤ connections, │ -│ └──────────┬────────────┘ │ data, etc. │ -│ ┌──────────┴────────────┐ └───────────────┘ -│ │ check │ -│ └──────────┬────────────┘ -│ ┌──────────┴────────────┐ -└──┤ close callbacks │ - └───────────────────────┘ + ┌───────────────────────────┐ +┌─>│ timers │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +│ │ pending callbacks │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +│ │ idle, prepare │ +│ └─────────────┬─────────────┘ ┌───────────────┐ +│ ┌─────────────┴─────────────┐ │ incoming: │ +│ │ poll │<─────┤ connections, │ +│ └─────────────┬─────────────┘ │ data, etc. │ +│ ┌─────────────┴─────────────┐ └───────────────┘ +│ │ check │ +│ └─────────────┬─────────────┘ +│ ┌─────────────┴─────────────┐ +└──┤ close callbacks │ + └───────────────────────────┘ ``` *note: 각 박스는 이벤트 루프의 "단계"를 의미합니다.* @@ -142,9 +142,12 @@ _**NOTE:** 윈도우와 Unix/Linux 구현체간에 약간의 차이가 있지만 * **timers**: this phase executes callbacks scheduled by `setTimeout()` and `setInterval()`. -* **pending callbacks**: executes I/O callbacks deferred to the next loop iteration. +* **pending callbacks**: executes I/O callbacks deferred to the next loop + iteration. * **idle, prepare**: only used internally. -* **poll**: retrieve new I/O events; execute I/O related callbacks (almost all with the exception of close callbacks, the ones scheduled by timers, and `setImmediate()`); node will block here when appropriate. +* **poll**: retrieve new I/O events; execute I/O related callbacks (almost + all with the exception of close callbacks, the ones scheduled by timers, + and `setImmediate()`); node will block here when appropriate. * **check**: `setImmediate()` callbacks are invoked here. * **close callbacks**: some close callbacks, e.g. `socket.on('close', ...)`. @@ -309,7 +312,7 @@ error. This will be queued to execute in the **pending callbacks** phase. The **poll** phase has two main functions: -1. Executing scripts for timers whose threshold has elapsed, then +1. Calculating how long it should block and poll for I/O, then 2. Processing events in the **poll** queue. When the event loop enters the **poll** phase _and there are no timers @@ -325,7 +328,7 @@ is reached. **poll** 단계는 두 가지 주요 기능을 가집니다. -1. 임계 값이 지난 타이머의 스크립트를 실행합니다. 그다음 +1. I/O를 얼마나 오래 블록하고 폴링해야 하는지 계산합니다. 그 다음 2. **poll** 큐에 있는 이벤트를 처리합니다. 이벤트 루프가 **poll** 단계에 진입하고 _스케줄링된 타이머가 없을 때_ @@ -413,11 +416,11 @@ emitted via `process.nextTick()`. @@ -762,7 +769,7 @@ server.on('listening', () => {}); ``` 포트만 전달하면 포트가 바로 바인딩 됩니다. 그래서 `'listening'` 콜백이 바로 호출될 수 있습니다. -문제는 `.on('listening')`이 이때 설정되지 않는다는 것입니다. +문제는 `.on('listening')` 콜백이 이때 설정되지 않는다는 것입니다. 이를 피하려면 `'listening'` 이벤트를 `nextTick()`으로 큐에 넣어서 스크립트가 완료될 때까지 실행되도록 할 수 있습니다. 이를 통해 어떤 이벤트 핸들러라도 설정하도록 할 수 있습니다. @@ -778,10 +785,10 @@ their names are confusing. event loop In essence, the names should be swapped. `process.nextTick()` fires more -immediately than `setImmediate()` but this is an artifact of the past +immediately than `setImmediate()`, but this is an artifact of the past which is unlikely to change. Making this switch would break a large percentage of the packages on npm. Every day more new modules are being -added, which mean every day we wait, more potential breakages occur. +added, which means every day we wait, more potential breakages occur. While they are confusing, the names themselves won't change. *We recommend developers use `setImmediate()` in all cases because it's @@ -847,9 +854,9 @@ server.on('listening', () => { }); `listen()`이 이벤트 루프 시작 부분에서 실행되었지만, listening 콜백은 `setImmediate()`에 -있습니다. 이제 바인딩할 호스트네임을 전달하지 않는 한 포트는 즉시 적용될 것입니다. 이제 이벤트 루프를 -진행하려면 **poll** 단계에 도달해야 하는데 이 말은 listening 이벤트 전에 connection 이벤트가 +있습니다. 바인딩할 호스트네임을 전달하지 않는 한 포트는 즉시 적용될 것입니다. 이벤트 루프를 +진행하려면 **poll** 단계에 도달해야 하는데, 이 말은 listening 이벤트 전에 connection 이벤트가 발생하도록 해서 연결을 받을 가능성이 있다는 것입니다. 또 다른 예제는 `EventEmitter`를 상속받고 생성자 내에서 이벤트를 호출하고자 하는 diff --git a/locale/zh-cn/docs/guides/event-loop-timers-and-nexttick.md b/locale/zh-cn/docs/guides/event-loop-timers-and-nexttick.md index dc7a98bde8d1..b0012546b8cd 100644 --- a/locale/zh-cn/docs/guides/event-loop-timers-and-nexttick.md +++ b/locale/zh-cn/docs/guides/event-loop-timers-and-nexttick.md @@ -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()` 就用户而言我们有两个类似的调用,但它们的名称令人费解。