javascriptreactjsasync-awaitpromise

Why does this code output order is not as expected by Promise-setTimeout-regular code chain in React


I'm confused by the output of the below code, simply it's like this;

setTimeout(() => {
    console.log("Timeot inner code");
  }, 500);

  promiseInner();

  console.log("Regular inner");

  useEffect(() => {
    setTimeout(() => {
      console.log("Timeout useEffect");
    }, 500);

    promiseUseEffect();

    console.log("Regular useEffect");
  }, []);

  async function promiseInner() {
    console.log("Promise inner");
  }
  async function promiseUseEffect() {
    console.log("Promise useEffect ");
  }

So one timeout first, then Promise, then a regular code followed by a useEffect. Aware that there is no await before Promises.

The output of above code is;

enter image description here

Which seems kinda weird, I've expected the below output;

Since Promise is a microtask but there is no await, I thought it will be executed after the regular code, but here it is executed before the regular code.

So I'm left with this question and completely have no idea what's going on.


Solution

  • The code in an async function is executed synchronously, up until the point it reaches an await. At that point, the function returns a promise. Since promiseInner and promiseUseEffect don't have any await, they do everything synchronously, and the only difference they have from a regular function is that when the function implicitly returns undefined at the end of execution, that undefined gets wrapped in a promise.

    If for some reason you want to force the async function to return its promise early and then do the log in a microtask you could do so like this:

    async function promiseInner() {
      await undefined;
      console.log("Promise inner");
    }
    

    This is not a normal thing to do though.