I was searching the proof of statement that in javascript promise handlers(then, catch) are enqueued in microtask queue after promise get resolved or rejected.
First is above statement true that javascript promise handlers(then, catch) are enqueued in microtask queue after promise get resolved or rejected?
So from section 27.2.5.4.1 PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] )
of ECMA specification 2024 I read that:
10. Else if promise.[[PromiseState]] is fulfilled, then
a. Let value be promise.[[PromiseResult]].
b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
It states that handler is queued in step 10.c. But my confusion is that in step 10.b it is calling NewPromiseReactionJob(fulfillReaction, value)
before HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]])
.
If i click on NewPromiseReactionJob(fulfillReaction, value)
it goes to section([27.2.2.1 NewPromiseReactionJob ( reaction, argument )][2]
) which contains following statement:
e. Else,
i. Let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)).
If I click on HostCallJobCallback(handler, undefined, « argument »)
it goes to section 9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )
which contains following statement:
The default implementation of HostCallJobCallback performs the following steps when called:
1. Assert: IsCallable(jobCallback.[[Callback]]) is true.
2. Return ? Call(jobCallback.[[Callback]], V, argumentsList).
Note the step 2. In this it is calling the handler.
This means Completion(HostCallJobCallback(handler, undefined, « argument »))
in section(27.2.2.1 NewPromiseReactionJob ( reaction, argument )
) is executing the handler before enqueuing it into microtask queue as mentioned by the order of statements:
10. Else if promise.[[PromiseState]] is fulfilled, then
a. Let value be promise.[[PromiseResult]].
b. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
c. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
which contradicts the statement that then and catch handlers are added to microtask queue after promise gets resolved.
Am i wrong or missing something here?
Yes, HostCallJobCallback does call the callback.
What you are missing is that in NewPromiseReactionJob, a new job is constructed but not actually executed:
- Let
job
be a new Job Abstract Closure with no parameters that capturesreaction
andargument
and performs the following steps when called:(emphasis mine)
It doesn't run steps 1. a) to i).