Skip to content

Commit

Permalink
Clarify when nextTick queue is processed
Browse files Browse the repository at this point in the history
Define an operation. Give example of dedup.

Remove empty section

Fix trigger happy deletions

Remove modififed REPL link

Spellcheck Deduplication section

Address Nits

* Remove italics.
* Change italics to bold

Move Deduplication sectino down

Update locale/en/docs/guides/event-loop-timers-and-nexttick.md

Co-Authored-By: OmarDarwish <[email protected]>

Update locale/en/docs/guides/event-loop-timers-and-nexttick.md

Co-Authored-By: OmarDarwish <[email protected]>
  • Loading branch information
OmarDarwish authored and Omar Darwish committed Dec 17, 2018
1 parent 6ff7342 commit 3317426
Showing 1 changed file with 55 additions and 2 deletions.
57 changes: 55 additions & 2 deletions locale/en/docs/guides/event-loop-timers-and-nexttick.md
Original file line number Diff line number Diff line change
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 Expand Up @@ -395,6 +398,56 @@ 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

0 comments on commit 3317426

Please sign in to comment.