Search code examples
javascriptasync-awaites6-promise

Await promise setTimout is working wrong?


The main function suppose to end after 6s but when running it only took 4s

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("promise1");
    resolve("promise1");
  }, 4000);
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("promise2");
    resolve("promise2");
  }, 2000);
});

async function main() {
  const result1 = await promise1;
  const result2 = await promise2;
  console.log("end");
}

main();

When i look at the terminal i notice that the output promise2 then promise1. Does the code supposed to run promise 1 then promise 2?

Can you guy help explain why and is there any way to await for the Promise in this scenario?


Solution

  • The function you pass to new Promise is called immediately. It is not triggered by await.

    The await keyword just suspends the main function until the promise on its RHS is resolved.

    1. You create the first promise
    2. You create the second promise
    3. You call main
    4. main is suspended until promise1 resolves
    5. Two seconds later promise2 resolves
    6. Two seconds after that promise1 resolves
    7. main wakes up
    8. main is suspended until promise2 resolves which already happened at step 5 so it wakes up again immediately

    If you want to avoid calling the function you pass to the second setTimeout until the the first promise has resolved, then put it in a function can call it from main at the time you want to call it.

    const func1 = () => new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("promise1");
        resolve("promise1");
      }, 4000);
    });
    
    const func2 = () => new Promise((resolve, reject) => {
      setTimeout(() => {
        console.log("promise2");
        resolve("promise2");
      }, 2000);
    });
    
    async function main() {
      const result1 = await func1();
      const result2 = await func2();
      console.log("end");
    }
    
    main();