为什么这个JavaScript async / await代码的行为不符合预期?

时间:2017-12-13 14:54:37

标签: javascript asynchronous async-await

我已经尝试过阅读指南和教程来异步/等待,但我似乎无法在任何地方找到它。

以下是相关代码:

    var func1 = new Promise((resolve, reject) => {
      console.log("Func1");
      setTimeout(() => {
        resolve(10);
      }, 100);
    });
    
    var func2 = new Promise((resolve, reject) => {
      console.log("Func2");
      setTimeout(() => {
        resolve(20);
      }, 5000);
    })
    
    let run = async() => {
      let var1 = await func1;
      let var2 = await func2;
      console.log(var1);
      console.log(var2);
    }

    run();

我们看到“Func1”和“Func2”立即打印,一个接一个。 5秒后,在func2中指定超时,我们打印“10”和“20”。到目前为止一切都很好。

但如果我将最后一段代码更改为:

let run = async() => {
  let var1 = await func1;
  console.log(var1);
  let var2 = await func2;
  console.log(var2);
}

然后我看到“Func1”立即打印,但“Func2”也是如此,即使console.log(var1)出现在它之前。 100ms后“10”,5秒后“20”。

来自MDN:

  

await表达式导致异步函数执行暂停,直到Promise完成或被拒绝,并在执行后继续执行async函数。

但似乎这不是正在发生的事情。如果是,我们不会看到“Func1”,然后是“10”,那么func2会被执行,因此打印“Func2”,5秒后我们得到“20”?应该执行func1,一旦解析(100毫秒),应触发console.log(var1)。我在这里缺少什么?

4 个答案:

答案 0 :(得分:7)

原因是您之前已经运行过您的承诺执行者。传递给Promise构造函数时,会立即评估Promise执行程序,因此您将获得以下内容:

var func1 = new Promise((resolve, reject) => ...); // Logs "Func1"
var func2 = new Promise((resolve, reject) => ...); // Logs "Func2"

let run = async() => {
  let var1 = await func1;
  console.log(var1); // Logs 10
  let var2 = await func2;
  console.log(var2); // Logs 20
}

run();

答案 1 :(得分:2)

这里的主要问题是func1func2不是函数;他们是承诺。就像Jonas W.所说,promises会立即调用他们的回调(resolve, reject) =>,等待他们只会让他们等到他们被解决。

您可以在此处查看所需结果:



var func1 = () => {
   return new Promise((resolve, reject) => {
    console.log("Func1");
    setTimeout(() => {
      resolve(10);
    }, 100);
  });
}
        
var func2 = () => {
  return new Promise((resolve, reject) => {
    console.log("Func2");
    setTimeout(() => {
      resolve(20);
    }, 5000);
  });
}
        
let run = async() => {
  let var1 = await func1();
  let var2 = await func2();
  console.log(var1);
  console.log(var2);
}

run();




答案 2 :(得分:1)

await基本上意味着确保在继续之前可以使用以下值。承诺在您创建时开始解析,等待时间无关紧要。

答案 3 :(得分:0)

运行功能是同步的,例如代码逐步采用它:

  1. 调用func1()并等到有回复。
  2. 调用func2()并等到有回复。
  3. log var1。
  4. log var2。
  5. 所以最后两个步骤只有在对func2()的调用完成了promise时才会运行,例如超时后的数据。所以它将等待整整5秒,直到记录var1和var2。

    另一种方式是完全不同的 1.调用func1()并等到有回复。 2. log var1。 3.调用func2()并等待有回复。 4. log var2。

    步骤2将等到第一步返回数据,例如在100ms之后,然后继续为第3步和第4步做同样的事情。