Skip to content

Commit

Permalink
doc: recommend queueMicrotask over process.nextTick
Browse files Browse the repository at this point in the history
We likely cannot ever deprecate process.nextTick, but we can start
steering people towards queueMicrotask for most cases.

Signed-off-by: James M Snell <[email protected]>
Fixes: #36870

PR-URL: #37484
Reviewed-By: Gus Caplan <[email protected]>
Reviewed-By: Robert Nagy <[email protected]>
  • Loading branch information
jasnell authored and targos committed Feb 28, 2021
1 parent e1045f1 commit 4a40759
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions doc/api/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -1722,6 +1722,70 @@ function definitelyAsync(arg, cb) {
}
```

### When to use `queueMicrotask()` vs. `process.nextTick()`

The [`queueMicrotask()`][] API is an alternative to `process.nextTick()` that
also defers execution of a function using the same microtask queue used to
execute the then, catch, and finally handlers of resolved promises. Within
Node.js, every time the "next tick queue" is drained, the microtask queue
is drained immediately after.

```js
Promise.resolve().then(() => console.log(2));
queueMicrotask(() => console.log(3));
process.nextTick(() => console.log(1));
// Output:
// 1
// 2
// 3
```

For *most* userland use cases, the `queueMicrotask()` API provides a portable
and reliable mechanism for deferring execution that works across multiple
JavaScript platform environments and should be favored over `process.nextTick()`.
In simple scenarios, `queueMicrotask()` can be a drop-in replacement for
`process.nextTick()`.

```js
console.log('start');
queueMicrotask(() => {
console.log('microtask callback');
});
console.log('scheduled');
// Output:
// start
// scheduled
// microtask callback
```

One note-worthy difference between the two APIs is that `process.nextTick()`
allows specifying additional values that will be passed as arguments to the
deferred function when it is called. Achieving the same result with
`queueMicrotask()` requires using either a closure or a bound function:

```js
function deferred(a, b) {
console.log('microtask', a + b);
}

console.log('start');
queueMicrotask(deferred.bind(undefined, 1, 2));
console.log('scheduled');
// Output:
// start
// scheduled
// microtask 3
```

There are minor differences in the way errors raised from within the next tick
queue and microtask queue are handled. Errors thrown within a queued microtask
callback should be handled within the queued callback when possible. If they are
not, the `process.on('uncaughtException')` event handler can be used to capture
and handle the errors.

When in doubt, unless the specific capabilities of `process.nextTick()` are
needed, use `queueMicrotask()`.

## `process.noDeprecation`
<!-- YAML
added: v0.8.0
Expand Down Expand Up @@ -2712,6 +2776,7 @@ cases:
[`process.kill()`]: #process_process_kill_pid_signal
[`process.setUncaughtExceptionCaptureCallback()`]: process.md#process_process_setuncaughtexceptioncapturecallback_fn
[`promise.catch()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch
[`queueMicrotask()`]: globals.md#globals_queuemicrotask_callback
[`readable.read()`]: stream.md#stream_readable_read_size
[`require()`]: globals.md#globals_require
[`require.main`]: modules.md#modules_accessing_the_main_module
Expand Down

0 comments on commit 4a40759

Please sign in to comment.