【问题标题】:Why await only works in async function in javascript?为什么 await 仅适用于 javascript 的异步函数?
【发布时间】:2021-10-03 09:47:35
【问题描述】:

刚刚浏览了这个tutorial,我很困惑为什么await 只在async 函数中有效。

来自教程:

如前所述,await 仅适用于异步函数。

据我了解,async将函数返回对象包装成一个Promise,所以调用者可以使用.then()

async function f() {
  return 1;
}

f().then(alert); // 1

await 只是等待承诺在async 函数中解决。

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  let result = await promise; // wait till the promise resolves (*)

  alert(result); // "done!"
}

f();

在我看来它们的用法不相关,有人可以解释一下吗?

【问题讨论】:

  • 这就是该功能的设计方式。将函数标记为async 的唯一原因是因为它在其中使用了await。回想一下,该语言必须继续完全正常地使用 2003 年编写的代码。
  • 您对async 所做的事情的猜测并不正确。调用者也可以自己使用await。基本上,asyncawait 提供了一种完全重新设计显式 Promise 使用模式的方法。
  • f() 返回result 时会发生什么?调用函数将立即获得一个返回值——它不知道您在f() 中使用await。使用异步函数,返回将是一个承诺。
  • 从 c# 复制粘贴。异步/承诺上的语法糖涂层。当我第一次看到它时,我的疑惑是一样的。
  • 就 OP 而言,async 似乎是多余的,解析器可以在没有人工的情况下将函数标记为异步(如果有 await),但也许这很慢或不支持 @ 987654342@ 或有些人有其他问题。

标签: javascript asynchronous async-await


【解决方案1】:

代码在 await 上变得异步 - 我们不知道要返回什么

await 除了等待 Promise 解决之外,它会立即将代码执行返回给调用者。 await之后的函数内部的所有代码都是异步的。

  • async 是返回承诺的语法糖。
  • 如果您不想在 await 返回承诺,那么异步代码中的明智选择是什么?

我们看下面的错误代码,看看返回值的问题:

function f() {
  // Execution becomes asynchronous after the next line, what do we want to return to the caller?
  let result = await myPromise;

  // No point returning string in async code since the caller has already moved forward.
  return "function finished";
}

我们可以问另一个问题:为什么我们没有同步版本的await 不会将代码更改为异步?

我的看法是,出于许多充分的原因,设计使异步代码同步变得困难。例如,人们很容易意外地使他们的整个应用程序冻结在等待异步函数返回时。


使用asyncawait 进一步说明运行时顺序:

async function f() {

  for(var i = 0; i < 1000000; i++); // create some synchronous delay

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("done!"), 1000)
  });

  console.log("message inside f before returning, still synchronous, i = " + i);

  // let's await and at the same time return the promise to the caller
  let result = await promise;
  console.log("message inside f after await, asynchronous now");

  console.log(result); // "done!"

  return "function finished";
}

let myresult = f();
console.log("message outside f, immediately after calling f");

控制台日志输出为:

message inside f before returning, still synchronous, i = 1000000 
message message outside f, immediately after calling f 
message inside f after await, asynchronous now 
done!

【讨论】:

  • "await 除了等待 Promise 解决之外,还会立即将代码执行返回给调用者。"第一句话对我帮助很大。
【解决方案2】:

asyncawait 都是元关键字,允许以看起来同步的方式编写异步代码。 async 函数提前告诉编译器该函数将返回 Promise 并且不会立即解析值。要使用await 而不阻塞线程async 必须使用。

async function f() {
    return await fetch('/api/endpoint');
}

等价于

function f() {
    return new Promise((resolve,reject) => {
        return fetch('/api/endpoint')
        .then(resolve);
    });
}

【讨论】:

  • 不过,这并不能回答 OP 的问题
猜你喜欢
  • 2019-04-27
  • 2022-06-18
  • 2019-06-14
  • 2016-08-12
  • 1970-01-01
  • 2019-04-05
  • 2011-10-18
  • 1970-01-01
相关资源
最近更新 更多