In the codebase of async-pool, there is this statement:
const p = Promise.resolve(iteratorFn(item, iterable));
I believe that this statement is equivalent to:
const p = Promise.resolve().then(() => iteratorFn(item, iterable));
...as both statements resolve a promise and execute iteratorFn(item, iterable)
asynchronously.
I would like to confirm if my assumption is correct and understand how I can validate it. I would then write appropriate unit tests to ensure the behavior of this code.
You wrote:
both statements resolve a promise and execute
iteratorFn(item, iterable)
asynchronously.
This is not true. The original code:
const p = Promise.resolve(iteratorFn(item, iterable));
...executes iteratorFn
synchronously. In other words, first iteratorFn
is executed, then resolve
, and then p
is assigned the resolved promise.
While here:
const p = Promise.resolve().then(() => iteratorFn(item, iterable));
resolve
is called first, then then
and then a pending(!) promise is assigned to p
. Code will then continue with whatever next statement is to be executed synchronously. The callback that has been passed to then()
will be called when the engine processes its microtask queue, so after the call stack is empty. Then iteratorFn
will get executed, which will resolve the promise p
.
We can see the difference in behaviour in this snippet:
function iteratorFn(arg) {
console.log("running iteratorFn with argument " + arg);
}
console.log("executing original code");
const p = Promise.resolve(iteratorFn("p"));
console.log("p has been assigned");
console.log("executing customised code");
const q = Promise.resolve().then(() => iteratorFn("q"));
console.log("q has been assigned");
console.log("------------- end of synchronous code -----------------");