Tomy Hoare将他发明的空引用(或空指针)描述为一个“价值十亿美元的错误”:由于无法抗拒放入空引用的诱惑,仅仅是因为它很容易实现。这导致了无数的错误、漏洞和系统崩溃,在过去四十年中可能造成了数十亿美元的痛苦和损害。
在这篇文章中,将解释为什么经常称async/await为“新的十亿美元错误”:在开发效率和bug方面,在过去十年中可能导致了数十亿美元的错误,特别是在Rust环境中。
函数着色是编程界的一个众所周知的问题,Bob Nystrom在2015年发表了一篇文章:What Color is Your Function?“红色(异步)函数”不能调用“蓝色(同步)函数”,反之亦然。在过去的日子里,你必须手工编写事件循环和状态机,然后花几年时间修复错误、崩溃和漏洞。在Rust中,使用async,它可以正常工作。编译器负责一切,为你生成状态机并确保它们是正确的。不是很棒,是棒极了!
那么,如果async/await实际上可以帮助开发人员更有效地使用机器,为什么称它为一个代价非常高昂的错误呢?
因为,如果执行不当,它会分裂生态系统和库:有同步库和异步库。开发人员对何时使用函数的异步版本或同步版本感到困惑。库开发人员花了很多努力来适应这两个世界,事件循环被同步调用阻塞。具有讽刺意味的是,由于单线程性质,JavaScript可能是唯一一种正确使用异步的语言:所有I/O调用都是异步的,因此语言和库在默认情况下都是异步的。
Rust在2019年11月发布async/await之后,Rust并没有在async上全速前进,我们现在陷入了一个奇怪的困境,很多(可能是大多数)开发人员每天都在使用异步,async和await是语言的关键字,但是没有官方的异步运行时,运行时甚至不兼容,更糟糕的是,标准库不提供任何异步I/O功能!
async,它是语言中的一等结构,但在生态系统中却是二等公民。难怪每个人都很困惑,不知道该怎么解决实际问题。
也许未来唯一的解决方案是Rust 2.0将异步作为真正的一等公民,就像JavaScript一样,其中每个I/O函数都将是异步的。有这么多聪明的人在Rust上工作,我们可以找到一些主要向后兼容的解决方案,这将使每个使用这门语言的人更轻松。