Search code examples
javascriptasync-awaites6-promise

What will happen if an async function intentionally returns a promise?


This is my code, I don't know what happened when I using the async keyword, if remove the async keyword, the result of print is different

async function async2() {
  return new Promise((resolve) => resolve('hello'))

}
async2().then((res) => {
  console.log(res)
  console.log('async1')
})

Promise.resolve()
  .then(() => {
    console.log(1)
  })
  .then(() => {
    console.log(2)
  })
  .then(() => {
    console.log(3)
  })

it will print

1
2
hello
async1
3

If remove the async keyword of async2 function, it will print

hello
async1
1
2
3

function async2() {
  return new Promise((resolve) => resolve('hello'))

}
async2().then((res) => {
  console.log(res)
  console.log('async1')
})

Promise.resolve()
  .then(() => {
    console.log(1)
  })
  .then(() => {
    console.log(2)
  })
  .then(() => {
    console.log(3)
  })

What will happen if an async function intentionally returns a promise?

I want to know what happened when I add the async keyword.


Solution

  • The difference is that an async function already returns a promise implicitly, and that promise is later resolved with the result value when the return statement is encountered:

    async function() {
      …;
      return new Promise(…);
    }
    

    is (in the simple case with no await in the ) equivalent to

    function() {
      return new Promise(resolve => {
        …;
        resolve(new Promise(…));
      })
    }
    

    However, resolving that implicit promise with your explicit new Promise(…) takes an extra tick or two in the promise job queue, which you can observe when starting the separate promise chain at the same time and all of the promises are immediately resolved, not actually doing any asynchronous work.

    In real code, the difference does not matter, and you should never need to care about such details, just like with other subtle execution order differences.