Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9df2edf

Browse files
committed
lib: run microtasks before ticks
This resolve multiple timing issues related to promises and nextTick. As well as resolving zaldo in promise only code, i.e. our current best practice of using process.nextTick will always apply and work. Refs: nodejs#51156 Refs: nodejs#51156 (comment) Refs: nodejs#51114 Refs: nodejs#51070 Refs: nodejs#51156 PR-URL: nodejs#51267
1 parent fc102f2 commit 9df2edf

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

doc/api/cli.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,20 @@ Use this flag to generate a blob that can be injected into the Node.js
787787
binary to produce a [single executable application][]. See the documentation
788788
about [this configuration][`--experimental-sea-config`] for details.
789789

790+
791+
### `--experimental-task-ordering`
792+
793+
<!-- YAML
794+
added: REPLACEME
795+
-->
796+
797+
> Stability: 1 - Experimental
798+
799+
Enable experimental task ordering. Always drain micro task queue
800+
before running `process.nextTick` to avoid unintuitive behavior
801+
and unexpected logical deadlocks when mixing async callback and
802+
event API's with `Promise`, `async`/`await`` and `queueMicroTask`.
803+
790804
### `--experimental-shadow-realm`
791805

792806
<!-- YAML

lib/internal/process/task_queues.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const {
4141

4242
const { AsyncResource } = require('async_hooks');
4343

44+
let experimentalTaskOrdering;
4445
// *Must* match Environment::TickInfo::Fields in src/env.h.
4546
const kHasTickScheduled = 0;
4647

@@ -65,8 +66,16 @@ function runNextTicks() {
6566
}
6667

6768
function processTicksAndRejections() {
69+
if (experimentalTaskOrdering === undeifned) {
70+
const { getOptionValue } = require('internal/options');
71+
experimentalTaskOrdering = getOptionValue('--experimental-task-ordering');
72+
}
73+
6874
let tock;
6975
do {
76+
if (experimentalTaskOrdering) {
77+
runMicrotasks();
78+
}
7079
while ((tock = queue.shift()) !== null) {
7180
const asyncId = tock[async_id_symbol];
7281
emitBefore(asyncId, tock[trigger_async_id_symbol], tock);
@@ -92,7 +101,9 @@ function processTicksAndRejections() {
92101

93102
emitAfter(asyncId);
94103
}
95-
runMicrotasks();
104+
if (!experimentalTaskOrdering) {
105+
runMicrotasks();
106+
}
96107
} while (!queue.isEmpty() || processPromiseRejections());
97108
setHasTickScheduled(false);
98109
setHasRejectionToWarn(false);

0 commit comments

Comments
 (0)