为什么在JavaScript函数体内需要异步来调用await? [英] Why is async required to call await inside a JavaScript function body?

查看:48
本文介绍了为什么在JavaScript函数体内需要异步来调用await?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

必须在包含函数上使用 async 关键字,才能在函数体内使用 await .

One has to use async keyword on the containing function to use the await inside the function body.

async function fetchMovies() {
  const response = await fetch('/movies');
  console.log(response);
}

fetchMovies();

等待用于在异步 fetch()调用完成时进行阻止.从代码中可以看出,函数 fetchMovies()甚至没有返回任何值.即使这样做,也会影响调用方使用返回值的方式,但是为什么从函数体中调用另一个异步调用就很重要呢?

The await is being used to block on completion of the asynchronous fetch() call. As can be seen in the code, the function fetchMovies() is not even returning any value. And even if it did, it would affect the way the return value is consumed by the caller, but why should it matter to the call to another asynchronous call from the function body?

我的问题是为什么?有一些很好的解释吗?是否与 await 的实际实现并在较旧的JavaScript版本中提供支持有关?

My question is why is this required? Is there some good explaination of that? Is it related to the need for actual implementation of await and supporting it in older JavaScript versions?

我知道 iffi 模式用于能够使用 await ,但这是否改变了 iffi 代码块后面的代码的语义以任何方式?

I know iffi pattern is used be able to use await but does that change the semantics for the code that follows the iffi code block in any way?

(async () => {
  const response = await fetch('/movies');
  console.log(response);
})();

我也知道模块中支持顶级 await .

I am also aware of top level await being supported in modules.

可能我遗漏了一些明显的东西.

May be I am missing something really obvious.

推荐答案

async 关键字存在的三个原因:

There are three reasons the async keyword exists:

  1. 在2015年之前的ECMAScript语言版本中, await 不是关键字.将功能标记为 async 可以提供语法上的紧急援助".表示该函数体内语言语法的重大变化.

  1. In ECMAScript language versions prior to 2015, await was not a keyword. Marking a function async provides a syntactic "bailout" to indicate a breaking change in the language grammar within the body of the function.

这是最重要的原因.如果没有 async 关键字,则使用ECMAScript 5或更早版本编写的所有程序如果将 await 关键字用作变量(实际上

This is the most important reason. Without the async keyword, all programs written in ECMAScript 5 or older would no longer work if they used the await keyword as a variable (in fact this was done intentionally in some cases as a polyfill before async/await was standardized), since that would cause a breaking change without the addition of async to the specification. Because of this, async is syntactically necessary to avoid breaking changes to the language.

它为解析器提供了一个方便的标记,避免了无限前行以确定函数是否异步.

It provides a convenient marker for parsers, avoiding an infinite look-ahead in order to determine whether or not a function is asynchronous.

这使解析更加高效,这对ECMAScript实现者和开发人员都具有吸引力,尽管仅此原因并不能使 async 严格地成为语法所必需的.

This makes parsing more efficient, which is appealing for both ECMAScript implementers and developers, though this reason alone does not make async strictly necessary to the syntax.

async 还在函数上执行其自己的转换,无论主体中是否存在 await 关键字,该转换都是完成的.

async also performs its own transformation on the function, which is done regardless of whether or not the await keyword is present in the body.

请考虑以下两个功能:

function foo() {
  if (Math.random() < 0.5) {
    return 'return';
  } else {
    throw 'throw';
  }
}

async function bar() {
  if (Math.random() < 0.5) {
    return 'return';
  } else {
    throw 'throw';
  }
}

async 执行以下对 function bar()的转换:

function bar() {
  return new Promise((resolve, reject) => {
    try {
      resolve((/*async function bar*/() => {
        if (Math.random() < 0.5) {
          return 'return';
        } else {
          throw 'throw';
        }
      })());
    } catch (reason) {
      reject(reason);
    }
  });
}

熟悉Promise的人会认识到,我们可以简化上述操作,因为Promise构造函数执行器函数将在同步引发错误时隐式拒绝它:

Those familiar with promises will recognize that we can simplify the above since the Promise constructor executor function will implicitly reject if it throws an error synchronously:

function bar() {
  return new Promise((resolve) => {
    if (Math.random() < 0.5) {
      return resolve('return');
    } else {
      throw 'throw';
    }
  });
}

这篇关于为什么在JavaScript函数体内需要异步来调用await?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆