返回

不要让你的promise被await击倒

前端

今天我们要讨论的是promise、async和await之间的关系。为什么这样认为呢?因为我们(粗浅地)知道await之后的语句会等await表达式中的函数执行完得到结果后,再去执行await后面的语句。

我们先来看一个例子:

function asyncFunction() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('异步函数执行完毕');
    }, 1000);
  });
}

async function main() {
  const result = await asyncFunction();
  console.log(result);
}

main();

这个例子中,我们定义了一个异步函数asyncFunction,它返回一个promise对象。然后,我们定义了一个async函数main,它使用await等待asyncFunction函数执行完毕,然后将结果打印到控制台。

运行这段代码,你会发现控制台会输出异步函数执行完毕。这表明await关键字确实会等待asyncFunction函数执行完毕,然后再执行await后面的语句。

但是,如果我们稍微修改一下代码,事情就会变得有点复杂了:

function asyncFunction() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('异步函数执行完毕');
    }, 1000);
  });
}

function main() {
  const result = asyncFunction();
  console.log(result);
}

main();

这段代码中,我们把asyncFunction函数的返回值从promise对象改成了直接返回字符串'异步函数执行完毕'。运行这段代码,你会发现控制台会输出Promise { '异步函数执行完毕' }。这表明await关键字并没有等待asyncFunction函数执行完毕,而是直接返回了asyncFunction函数的返回值。

这是因为await关键字只对promise对象有效。如果await表达式中的函数不返回promise对象,那么await关键字就什么都不会做。

因此,如果你想使用await关键字来等待异步函数执行完毕,那么你需要确保异步函数返回一个promise对象。

总结一下,promise、async和await之间的执行顺序是:

  1. 首先,JavaScript引擎会执行async函数中的所有同步代码。
  2. 然后,JavaScript引擎会执行await表达式中的函数,并等待该函数返回一个promise对象。
  3. JavaScript引擎会暂停执行async函数,直到await表达式中的函数执行完毕并返回一个promise对象。
  4. JavaScript引擎会恢复执行async函数,并将await表达式中的promise对象的值赋给await表达式后的变量。
  5. JavaScript引擎会继续执行async函数中的剩余代码。

希望这篇博文对promise、async和await之间的执行顺序的理解有所帮助。如果你有任何问题,请随时留言。