skip to Main Content

I saw many issues of setTimeout not waiting even with await keyword and the answers were like use it with a promise, but I still don’t get it.

Doesn’t async function implicitly return a promise? so, from the below code the function f which has a setTimeout inside returns promise? and can be valid with the await keyword.

const f = async(x) => {
    setTimeout(() => {
      console.log(x, 'done!!!')
    }, x)
  }
  (async() => {
    await f(2000)
    await f(1000)
    await f(500)
    console.log('all done!')
  })()

my expected result:

2000 done!!!

1000 done!!!

500 done!!!

all done!

const f = async(x) => {
  setTimeout(() => {
    console.log(x, 'done!!!')
  }, x)
}

(async() => {
  await (async() => {
    f(2000)
    f(1000)
    f(500)
  })()
  console.log('all done!')
})()

my expected result:

500 done!!!

1000 done!!!

2000 done!!!

all done!

2

Answers


  1. The following code will return result as below.

    output:-

    This is because of event loop handling and not async/await.

    yes, the async function implicitly returns a promise, but you must use ‘then’ for sequential execution.

    Login or Signup to reply.
  2. doesn’t async function implicitly returns promise?

    Yes, by making a function async, that function will return a promise. But if you don’t have any await‘s in your code, that promise is going to resolve right away.

    Let’s step through this code:

    async (x) => {
      setTimeout(()=>{console.log(x, 'done!!!')}, x)
    }
    

    The function starts running. It calls setTimeout, asking javascript to call the function () => {console.log(x, 'done!!!')} after x milliseconds have expired. Javascript takes note of this request, and your function continues. There are no more lines of code, so your function is done. It implicitly returns an undefined, which gets wrapped in a promise.

    End result: a timer has been started, but not finished, and whoever called f gets back a promise in the resolved state. awaiting that promise doesn’t cause any delay, because the promise is already resolved. Some time later, the timeout will go off and the console.log will happen, but this doesn’t affect when the promise returned by f resolves.

    If you want to set a timeout and wrap it in a promise, then use the new Promise constructor:

    const f = (x) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => resolve(), x);
      });
    }
    
    // Or shorter:
    const f = (x) => {
      return new Promise((resolve) => {
        setTimeout(resolve, x);
      });
    }
    

    When this version of f runs, you start creating a new promise. While constructing the promise, you set a timeout and ask javascript to call a function after x milliseconds. Then you return this promise, which is still in the pending state. Awaiting this promise will cause your code to pause. Some time later, the timeout goes off, and you call resolve. Now that the promise is resolved, any code which is awaiting it can continue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search