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 <jasnell@gmail.com>
Fixes: #36870

PR-URL: #37484
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
  • Loading branch information
jasnell authored and targos committed May 1, 2021
1 parent bcc4f17 commit 2082f5b
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions doc/api/process.md
Expand Up @@ -1699,6 +1699,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 @@ -2671,6 +2735,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 2082f5b

Please sign in to comment.