From 94669e1246496c8649ac194c2cc0d85b957311e8 Mon Sep 17 00:00:00 2001 From: Dario Piotrowicz Date: Tue, 21 Jan 2025 17:16:17 +0000 Subject: [PATCH] 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 Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- doc/api/process.md | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/doc/api/process.md b/doc/api/process.md index 8e7fe148daa9a6..a711b3685662a5 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -2993,34 +2993,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