为什么我必须将 async 关键字放在具有 await 关键字的函数中?

Why do I have to put async keyword to functions which have await keywords?

我只想等待一个进程完成,不想让函数异步。
请看下面的代码。
我必须使 getUserList 异步,因为函数中有一个 await 关键字。因此,我还必须像 "await UsersService.getUserList" 这样写来执行该方法,而且我还必须使父函数异步。那不是我想做的。

import xr from 'xr' //a package for http requests

class UsersService {

  static async getUserList() {
    const res = await xr.get('http://localhost/api/users')
    return res.data
  }

}

export default UsersService

import UsersService from './UsersService'

class SomeClass {

  async someFunction() { //async again!!
    const users = await UsersService.getUserList() //await again!!
  }

}

这是设计选择吗?

嗯,这是因为 JavaScript 的同步性质。如果你想要一个函数同步地 运行 一个异步命令,它会阻塞整个程序,这是非常不可取的,如果它是客户端就很糟糕,如果它是服务器端就很糟糕。因此存在 async 个函数。这些功能是从正常流程中取出的,这就是 await 起作用的原因。

为什么?

另一个原因是 await+async 是 promise 的 语法糖 。 Promises 是异步的,您无法阻止它。这意味着 await 不会使异步函数 sync,它只是暂停 await 函数的其余部分直到它完成。如果它确实阻塞了整个事件循环,想象一下如果您想创建一个可以在客户端之间发送数据的应用程序。每次发出异步请求时,您的整个服务器应用程序都会挂起,而不是仅仅使单个请求异步。

所以这样想:

您不是在使异步函数同步,而是在使程序的其余部分异步以应对它。

因此,与其将 async 视为 await 的要求,不如将它们视为组合 (async+await),因为这就是它们的基本工作方式。如果您想了解更多关于 async 和 await 的信息,我强烈建议您阅读我的 blog article,其中有深入的内容。