为什么 Javascript 中的等待/异步不能按预期工作?

Blu*_*hin 5 javascript async-await

作为学习 Javascript 中的 async/await 的一种方法,我创建了以下 JSFiddle 示例代码

async function func1() {
  return await setTimeout(() => {
    console.log('execute func1');
  }, 5000);
}

async function func2() {
  return await setTimeout(() => {
    console.log('execute func2');
  }, 2000);
}

async function mainFunc() {
    await func1();
  await func2();

  console.log('execute completed'); 
}

mainFunc();
Run Code Online (Sandbox Code Playgroud)

由于我已经等待,我预计输出将是:

execute func1
execute func2
execute complete
Run Code Online (Sandbox Code Playgroud)

但令我惊讶的是,输出是

execute complete
execute func2
execute func1
Run Code Online (Sandbox Code Playgroud)

我一定错过了一些重要的概念,非常欢迎任何建议。

Eur*_*eka 9

您必须在 func1 和 func2 内创建一个承诺

一旦你掌握了窍门,这很容易做到,但如果你没有练习过,那就不太明显了。

setTimeout本身不返回承诺:它返回对计时器的引用,可用于取消超时过程。

要获取 Promise,请使用new Promise构造函数。在简单的使用中,您输入单词resolve以及您想要运行的函数(在本例中为 )setTimeout。当您的函数中想要返回结果时,不要使用return: 而是使用resolve

例如,如果您想42在 1 秒延迟后返回数字,您可以使用以下命令。事实上,它立即返回一个承诺,1 秒后解析为 number 42。要获得延迟后返回值的效果,您需要await结果。

return new Promise(resolve, setTimeout(()=>{resolve(42)},1000)
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您不想从 setTimeout 返回任何特定结果,因此您不需要将任何内容放在 的括号内resolve

该词resolve实际上是一个虚拟函数名称:您可以使用任何变量名称,但通常会调用它resolve以防止读者产生不必要的困惑。

return new Promise(resolve, setTimeout(()=>{resolve(42)},1000)
Run Code Online (Sandbox Code Playgroud)