javascriptasync-awaitpromiseevent-loop

Async/await promises alternative. Rewrite await to Promise


I was trying to understand how await works in different scenarious, and camse across a problem.

new Promise(async (resolve, reject) => {
    resolve(); 

    console.log(await Promise.resolve(7))
    
    console.log(8)
}).then(() => console.log(3))

this code logs 7, 8, 3 - so it doesn't put console.log to microtasks queue. (that's the thing I don't understand.
So, I tried to rewrite await line to Promise syntax:

new Promise(async (resolve, reject) => {
    resolve(); 

    const pr = new Promise((res) => {
        res(7)
    })
    pr.then((num) => console.log(num))
    
    console.log(8)
}).then(() => console.log(3))

But now it puts then to microtasks queue and logs 8 first.
Logs: 8, 7, 3.

The question is: why my attempt to recreate console.log(await Promise.resolve(7)) is incorrect?
Why await Promise.resolve() executes immediately?


Solution

  • The rule is simple: await puts all the code below it and everything outside its expression on its line into a microtask:

    <script type="module">
    
        console.log ( ( await Promise.resolve({name: 'John'}) ).name );
    //                        -------------------------------              this is executed sync (first)
    //  --------------                                         -------     this is executed in the created microtask
    //  all the code below is executed also in the created microtask
    </script>

    So your console.log(8) is indeed put into a microtask but as you can analyze it's put last in the first microtask.

    new Promise(async (resolve, reject) => {
        resolve();
    
        console.log(await Promise.resolve(7)) // await puts both the console.log's into the first microtask
        
        console.log(8)
    }).then(() => console.log(3)) // then puts the callback into the second microtask

    Let's change a bit to learn more how it works:

    <script type="module">
    
    new Promise((resolve, reject) => {
        resolve(); 
    }).then(() => console.log(3)) // then puts the callback into the first microtask
    
    await 1; // puts the below code into the second microtask 
    
    console.log(await Promise.resolve(7)) // both the console.log's are put into the third microtask
    
    console.log(8)
    
    </script>