【问题标题】:await destroys orderawait 破坏订单
【发布时间】:2020-01-23 18:11:14
【问题描述】:

请解释一下,为什么 await 关键字会导致 Hello World 文本放置在中间(第一个示例)和末尾(第二个示例)输出?

第一个例子:

const getData = async() => { 
    var y = "Hello World"; 
    console.log(y); 
} 

console.log(1); 
getData(); 
console.log(2); 

第一个例子的输出:

1
Hello World
2

第二个例子:

const getData = async() => { 
    var y = await "Hello World"; 
    console.log(y); 
} 

console.log(1); 
getData(); 
console.log(2); 

第二个例子的输出:

1
2
Hello World

【问题讨论】:

标签: javascript asynchronous async-await


【解决方案1】:

两个示例都返回Promise,但是脚本引擎正在寻找一个关键的区别......其中是否有任何异步等待?在第一个示例中没有,但在第二个示例中,代码至少 存在。 (虽然我可能希望任何像样的 IDE 都会抱怨它,因为字符串文字不是异步操作。不过,语言本身可以很宽容。)

即使您在第一个示例中执行了异步操作,除非您等待它,否则周围的代码仍将同步运行。您将无法观察该操作的结果(或失败)。 (好吧,您可以将.then() 附加到它上面,但是为什么要使用async?那时您将混合您的异步约定。)

如果您在 async 函数中调用 getData(),那么您可以等待它:

console.log(1);
await getData();
console.log(2);

或者,您可以从返回的承诺继续:

console.log(1);
getData().then(() => console.log(2));

或者,更冗长(或任何卡在 IE 中的人):

console.log(1);
getData().then(function () {
    console.log(2);
});

【讨论】:

  • 请解释一下为什么第一个示例即使被标记为异步也不返回承诺。谢谢
  • @AdamOstrožlík:诚然,在您的示例中我没有注意到这一点。这主要是一个猜测,但我怀疑这是因为其中没有使用 await 并且解释器足够聪明,可以知道这一点并同步执行操作。第二个示例中的 await 关键字当然不是必需的,任何体面的 IDE 都应该抱怨它,但该语言可能会照本宣科,并假设整体功能需要是一个承诺。
  • 第一个例子确实返回一个Promise。但是,由于函数内部没有await,因此整个代码同步运行完成。返回值仍然是 Promise,但由于它从未使用过,因此无关紧要。
  • @David:那么你认为如果在第一个示例中有一些 fetch api 调用,该函数会返回一个 Promise 吗?
  • @David 是的,await 实际上是将执行转移到稍后执行的唯一方法。如果你有await <expression>; <any code>; <return expression>,它会在后台更改为return new Promise((resolve) => {<any code>; resolve(<return expression>)})。好吧,如果您使用仍然可用的 await-ed 值,但基本上其余代码只是包装在 Promise 中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 2019-06-15
  • 1970-01-01
  • 2016-02-20
相关资源
最近更新 更多