the code snippet likes below:
console.log('test')
async function async1() {
console.log('before wait');
await wait();
console.log('after wait');
}
async function wait() {
try {
return await new Promise((res, rej) => {
console.log('wait');
rej('reject');
});
} catch (reason) {
console.log(reason);
}
}
async function test() {
async1();
console.log('before resolve');
await Promise.resolve();
console.log('after resolve');
}
test();
console.log('test end');
you can also run the code in playground
actual result:
[LOG]: "test"
[LOG]: "before wait"
[LOG]: "wait"
[LOG]: "before resolve"
[LOG]: "test end"
[LOG]: "reject"
[LOG]: "after resolve"
[LOG]: "after wait"
I thought after wait
would be printed first, since it is pushed in the micro task queue early?
where am I wrong?
I took advice from @Seblor
It may become clearer if you replace the async/await with the then function.
then I removed all the async/await
console.log('test')
function async1() {
console.log('before wait');
return wait().then(() => {
console.log('after wait');
})
}
function wait() {
return new Promise((res, rej) => {
console.log('wait');
rej('reject');
}).catch((reason) => {
console.log(reason);
})
}
function test() {
async1();
console.log('before resolve');
Promise.resolve().then(() => {
console.log('after resolve');
})
}
test();
console.log('test end');
Then I realized the first code pushed in micro task queue is the code in catch
, followed by console.log('after resolve')
, finally console.log('after wait')
2
Answers
In given snippet, it is not waiting for
Promise.resolve()
to return any response because it is not waiting for any operation. To get rid of this we can simply use chaining of functions likeOkay I had a hard time spotting it but I think I get it.
So we all agree where the issue is, the problem you see is that the promise rejection is executed before the promise that resolves, but the ‘after resolve’ is printed before ‘after wait’.
The thing is that even though there are 2 promises, there are 3 micro tasks here. The first one is the
return await new Promise(
, the second one isawait Promise.resolve()
, and the 3rd one is the awaiting of the call to the function:await wait()
.The call to
wait()
returns a promise, which youawait
, creating a new microtask that is queued AFTERawait Promise.resolve()
.So the rejecting promise finished, printing ‘reject’, then the resolving promise finished, printing ‘resolve’, and finally the returned promise from
wait()
is awaited, printing ‘after wait’.It may become clearer if you replace the async/await with the
then
function. So this:Would be written like this:
So in order of execution (of the micro tasks only):
await new Promise((res, rej) => {
registers the 1st Promiseawait Promise.resolve()
registers the 2nd Promisethen
callback, creating the 3rd microtask.