为什么我必须将异步关键字放在具有 await 关键字的函数上

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

本文关键字:关键字 await 函数 异步 为什么      更新时间:2023-09-26

我只想等待一个进程完成,不想使函数异步。
请参阅下面的代码。
我必须使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是承诺的语法糖。承诺是异步的,你无法阻止它。这意味着 await 不会使异步函数同步,它只是保留 await 函数的其余部分,直到它完成。如果它确实阻塞了整个事件循环,想象一下,如果你想创建一个在客户端之间发送数据的应用程序。您的整个服务器应用程序每次发出异步请求时都会挂起,而不仅仅是使单个请求异步。

所以可以这样想:

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

因此,与其认为async await的要求,不如将它们视为组合(async + await),因为这就是它们的基本工作方式。如果您想了解有关异步和等待的更多信息,我强烈建议您阅读我的博客文章,其中对此进行了深入探讨。