为什么在JavaScript函数体内调用await需要异步?

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

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

fetchMovies();

AWAIT被用来对异步完成方框取()调用。从代码中可以看出,函数fetchMovies()甚至没有返回任何值。即使这样做了,它也会影响调用者使用返回值的方式,但是为什么它会影响从函数体调用另一个异步调用呢?

我的问题是为什么需要这样做?有什么好的解释吗?它是否与实际实现await的需要有关,并在旧的 JavaScript 版本中支持它?

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

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

我也知道模块中支持顶级等待

可能是我错过了一些非常明显的东西。

回答

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

  1. 在 2015 年之前的 ECMAScript 语言版本中,await不是关键字。标记函数async提供了句法“救助”以指示函数主体内语言语法的重大变化。

    这是最重要的原因。如果没有async关键字,所有用 ECMAScript 5 或更早版本编写的程序如果使用await关键字作为变量将不再工作(事实上​​,在某些情况下,这是有意在async/await标准化之前作为 polyfill 完成的),因为这会导致重大更改没有添加async到规范中。因此,async在语法上是必要的,以避免对语言进行破坏性更改

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

    这使得解析更高效,这对 ECMAScript 实现者和开发人员都很有吸引力,尽管仅凭这个原因并不能async严格要求语法。

  3. async还对函数执行自己的转换,无论await关键字是否存在于主体中,都会进行转换。

    考虑以下两个函数:

    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 构造函数 executor 函数在同步抛出错误时将隐式拒绝:

    function bar() {
      return new Promise((resolve) => {
        if (Math.random() < 0.5) {
          return resolve('return');
        } else {
          throw 'throw';
        }
      });
    }
    
  • Also, as I understand it, async/await as a syntax existed in C# a few years before it was in ES, and Python somewhere in-between. I wouldn't be surprised if that played an influence. Of course, that's begging the question a bit, as your reasons above surely apply to the predecessor languages as well.

以上是为什么在JavaScript函数体内调用await需要异步?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>