When does Promise resolve/reject actually add a micro task?
I read the Promise/A+ implementation code from here, and understood that task adding action is triggered after resolve()
(the mentioned implementation do it by timer callback, but from GPT's info, it seems to be micro task in real Promise implementation, then the onFulfilleds queue on the chain will be executed one by one).
However, when I run the code below, I get the result I didn't expect:
function a() {
return new Promise((resolve) => {
resolve();
new Promise((r) => {
r();
}).then(() => {
console.log("1")
});
})
}
await a();
console.log("2");
or
new Promise((resolve) => {
resolve();
new Promise((r) => {
r();
}).then(() => {
console.log("1")
});
}).then(() => {
console.log("2")
})
I expected both the code pieces will log 2
then 1
, but they both log 1
then 2
, why I expect so:
resolve()
add a micro task (provided by then) to queue which logs 2
r()
add a micro task to queue which logs 1
2
then 1
.but the result is 1
then 2
, what did I mis-understand, I want to know it so bad.
I understood that task adding action is triggered after
resolve()
No; or: only when there is already registered callbacks. In general, what is delayed is the then
callback execution (or await
resumption), not the resolution of the promise itself.
the outer Promise's
resolve()
add a micro task (provided bythen
) to queue
Notice that the new Promise
executor callback runs synchronously, so it has called resolve()
before the .then()
method call happens. There is no task to schedule yet when the promise is getting resolved.
So all what is happening in your examples is that you are creating immediately-resolved promises, and then attaching then
handlers on them - the same as
const a = Promise.resolve(); // or new Promise(resolve => { resolve(); })
const b = Promise.resolve();
b.then(() => {
console.log("1")
});
a.then(() => {
console.log("2")
});
Given it's the .then()
call on the fulfilled promise where the microtask queuing happens, the output is not unexpected.