From 0503f9c200fb219726d477d71f7a3f1217ac480f Mon Sep 17 00:00:00 2001 From: Andreas Marek Date: Wed, 18 Dec 2024 06:39:26 +1000 Subject: [PATCH 1/3] Update enqueue promise jobs description I found the enqueue promise jobs description hard to digest with several names and concepts referenced. I tried to make it more clear. --- src/index.js | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/src/index.js b/src/index.js index 997d85a..b207a74 100644 --- a/src/index.js +++ b/src/index.js @@ -217,26 +217,27 @@ class DataLoader { // after the current execution context has completed: // http://www.ecma-international.org/ecma-262/6.0/#sec-jobs-and-job-queues // -// Node.js uses the `process.nextTick` mechanism to implement the concept of a -// Job, maintaining a global FIFO JobQueue for all Jobs, which is flushed after -// the current call stack ends. -// // When calling `then` on a Promise, it enqueues a Job on a specific -// "PromiseJobs" JobQueue which is flushed in Node as a single Job on the -// global JobQueue. -// -// DataLoader batches all loads which occur in a single frame of execution, but -// should include in the batch all loads which occur during the flushing of the -// "PromiseJobs" JobQueue after that same execution frame. +// "PromiseJobs" JobQueue which is flushed "recursively" until it +// is empty, including new Promise Jobs that are added during the current +// flushing. // -// In order to avoid the DataLoader dispatch Job occuring before "PromiseJobs", -// A Promise Job is created with the sole purpose of enqueuing a global Job, -// ensuring that it always occurs after "PromiseJobs" ends. +// DataLoader batches all loads which occur in a single frame of execution +// (synchronously executed code), but should include in the batch all loads +// which occur during the flushing of the "PromiseJobs" JobQueue after that +// same execution frame. +// +// In Node.js we can use `process.nextTick` that is run +// immediately after the "PromiseJobs" is empty. +// +// Browsers do not have an equivalent mechanism, therfore +// we use `setImmediate` or `setTimeout` which is always run after all Promise +// jobs. This might be less efficient that `nextTick`, which is ensured to +// run directly after the all Promise jobs are done. // -// Node.js's job queue is unique. Browsers do not have an equivalent mechanism -// for enqueuing a job to be performed after promise microtasks and before the -// next macrotask. For browser environments, a macrotask is used (via -// setImmediate or setTimeout) at a potential performance penalty. +// In either environment we wrap `nextTick`, `setImmedidate` or `setTimeout` +// in a Promise handler itself, to ensure the flushing of "PromiseJobs" has +// started. const enqueuePostPromiseJob = typeof process === 'object' && typeof process.nextTick === 'function' ? function (fn) { From 4c2ae505db746f6c5a60e8bc3777b85cc242fc36 Mon Sep 17 00:00:00 2001 From: Andreas Marek Date: Wed, 18 Dec 2024 08:42:47 +1000 Subject: [PATCH 2/3] fix eslint, typos --- src/index.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/index.js b/src/index.js index b207a74..b982331 100644 --- a/src/index.js +++ b/src/index.js @@ -218,25 +218,25 @@ class DataLoader { // http://www.ecma-international.org/ecma-262/6.0/#sec-jobs-and-job-queues // // When calling `then` on a Promise, it enqueues a Job on a specific -// "PromiseJobs" JobQueue which is flushed "recursively" until it -// is empty, including new Promise Jobs that are added during the current +// "PromiseJobs" JobQueue which is flushed "recursively" until it +// is empty, including new Promise Jobs that are added during the current // flushing. // // DataLoader batches all loads which occur in a single frame of execution -// (synchronously executed code), but should include in the batch all loads -// which occur during the flushing of the "PromiseJobs" JobQueue after that +// (synchronously executed code), but should include in the batch all loads +// which occur during the flushing of the "PromiseJobs" JobQueue after that // same execution frame. -// -// In Node.js we can use `process.nextTick` that is run +// +// In Node.js we can use `process.nextTick` that is run // immediately after the "PromiseJobs" is empty. -// -// Browsers do not have an equivalent mechanism, therfore -// we use `setImmediate` or `setTimeout` which is always run after all Promise -// jobs. This might be less efficient that `nextTick`, which is ensured to +// +// Browsers do not have an equivalent mechanism, therefore +// we use `setImmediate` or `setTimeout` which is always run after all Promise +// jobs. This might be less efficient that `nextTick`, which is ensured to // run directly after the all Promise jobs are done. // -// In either environment we wrap `nextTick`, `setImmedidate` or `setTimeout` -// in a Promise handler itself, to ensure the flushing of "PromiseJobs" has +// In either environment we wrap `nextTick`, `setImmediate` or `setTimeout` +// in a Promise handler itself, to ensure the flushing of "PromiseJobs" has // started. const enqueuePostPromiseJob = typeof process === 'object' && typeof process.nextTick === 'function' From 007e5cb7989367b74996d92286ed7db6f208cc72 Mon Sep 17 00:00:00 2001 From: Andreas Marek Date: Wed, 18 Dec 2024 11:42:36 +1000 Subject: [PATCH 3/3] improve comment --- src/index.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/index.js b/src/index.js index b982331..6069d4d 100644 --- a/src/index.js +++ b/src/index.js @@ -227,17 +227,15 @@ class DataLoader { // which occur during the flushing of the "PromiseJobs" JobQueue after that // same execution frame. // -// In Node.js we can use `process.nextTick` that is run -// immediately after the "PromiseJobs" is empty. +// In Node.js we wrap `nextTick`in a Promise handler itself, to ensure the +// flushing of "PromiseJobs" has started, otherwise the dispatch would happen +// before the Promise handlers are called. // -// Browsers do not have an equivalent mechanism, therefore -// we use `setImmediate` or `setTimeout` which is always run after all Promise -// jobs. This might be less efficient that `nextTick`, which is ensured to +// Browsers do not have an equivalent mechanism to `nextTick`, therefore +// we use `setImmediate` or `setTimeout`, which is always run after all Promise +// jobs. This might be less efficient than `nextTick`, which is ensured to // run directly after the all Promise jobs are done. // -// In either environment we wrap `nextTick`, `setImmediate` or `setTimeout` -// in a Promise handler itself, to ensure the flushing of "PromiseJobs" has -// started. const enqueuePostPromiseJob = typeof process === 'object' && typeof process.nextTick === 'function' ? function (fn) {