doc: clarify cjs/esm diff in `queueMicrotask()` vs `process.nextTick()`

the section comparing `queueMicrotask()` and `process.nextTick()`
doesn't address the different scheduling behavior that the two
functions have in cjs and esm modules, the section's introductory mjs
example also provides an incorrect output, the changes here address
such by explaining the difference between the two module types and
updating the example accordingly

PR-URL: https://github.com/nodejs/node/pull/56659
Fixes: https://github.com/nodejs/node/issues/45048
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
pull/56451/merge
Dario Piotrowicz 2025-01-21 17:16:17 +00:00 committed by GitHub
parent d07c60b08f
commit 23c2d33592
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 22 additions and 16 deletions

View File

@ -3020,34 +3020,40 @@ 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
The [`queueMicrotask()`][] API is an alternative to `process.nextTick()` that instead of using the
"next tick queue" 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.
So in CJS modules `process.nextTick()` callbacks are always run before `queueMicrotask()` ones.
However since ESM modules are processed already as part of the microtask queue, there
`queueMicrotask()` callbacks are always exectued before `process.nextTick()` ones since Node.js
is already in the process of draining the microtask queue.
```mjs
import { nextTick } from 'node:process';
Promise.resolve().then(() => console.log(2));
queueMicrotask(() => console.log(3));
nextTick(() => console.log(1));
Promise.resolve().then(() => console.log('resolve'));
queueMicrotask(() => console.log('microtask'));
nextTick(() => console.log('nextTick'));
// Output:
// 1
// 2
// 3
// resolve
// microtask
// nextTick
```
```cjs
const { nextTick } = require('node:process');
Promise.resolve().then(() => console.log(2));
queueMicrotask(() => console.log(3));
nextTick(() => console.log(1));
Promise.resolve().then(() => console.log('resolve'));
queueMicrotask(() => console.log('microtask'));
nextTick(() => console.log('nextTick'));
// Output:
// 1
// 2
// 3
// nextTick
// resolve
// microtask
```
For _most_ userland use cases, the `queueMicrotask()` API provides a portable