当前位置:首页 > 技术分析 > 正文内容

对异步编程的重新思考:Async/Await是否真的是解决方案?

ruisui883个月前 (02-14)技术分析15

我今天看到这个图:

说到async和await,它们可能是开发者对异步编程爱恨交加的原因之一。如果你让一个函数等待异步代码,那么这个函数也必须是异步的,而任何依赖它的函数同样也必须是异步的。这种层层递进的模式让代码像病毒一样被“异步化”,直到最终传递到顶层。

我对Async/Await的看法

老实说,我一直对这种模式感到厌烦。尽管它可能是目前的最佳实践,但仍然让人觉得这是种“必要之恶”。直到我开始接触Go。

Go没有async和await,但它以并发编程闻名。起初,我觉得奇怪:没有这些关键字,Go是怎么做到并发的?

举个例子,当我开发一个应用时,需要为请求增加一秒的延迟,以避免频繁访问被限制。我用Go实现延迟,只需一行代码:

time.Sleep(1*time.Second)

简单到让人难以置信。更奇妙的是,Go没有await,但延迟依然可以正常工作。这让我很好奇:如果没有await,延迟是如何实现的?它会使用效率极低的自旋锁吗?答案是否定的。

事实证明,Go的线程调度器可以高效地让线程进入休眠状态,而无需依赖复杂的await语法。这是一次颠覆性的体验。

我讨厌“聪明”的设计

我认为函数应该是简单的:接受参数、执行操作、返回结果。而像async、await这样复杂的附加机制,让代码的逻辑变得难以直观理解。

还有其他复杂机制,比如生成器。以Python为例:

deffoo():
 yield1
 yield2
 yield3

这看似简单,但如果不了解生成器的原理,理解代码的意图就不那么容易了。在Dart中,生成器同样不算直观:

IterablesimpleGeneratorFun()sync*{
 yield1;
 yield2;
 yield3;
}

这样的“聪明”工具似乎在告诉你,“代码逻辑比你想象的复杂”,这让我感到不适。

Go的方式

在Go中,我们用简单直接的方式处理并发。你可以通过go func()创建一个新的协程,而无需标记函数为异步。

虽然多线程可能带来复杂的错误,但async/await也无法完全解决这些问题。真正高效的解决方案可能是像Dart隔离那样的独立内存机制,而不是强制异步。

“异步病毒”与性能

异步函数不仅会“感染”其他函数,还可能拖慢性能。比如,调度器的额外参与可能反而增加开销。而某些情况下,同步代码甚至更优:Dart的lint工具avoid_slow_async_io就建议使用同步版本的文件操作,如existsSync替代exists。

反思Async/Await

如果每次获取当前时间都需要异步等待,那无疑是灾难。我们需要问自己:真的有必要强制所有异步操作显式标记为异步吗?

其实,第一种引入async/await的语言是C#,或更准确地说是F#。虽然它们确实解决了一些问题,但也将异步运行代码的复杂性推到了每一层函数中。

异步编程本身没有问题,但async/await的设计却强加了许多不必要的复杂性。它是现代编程中最大的设计失误之一。而Go的方式则证明,简单直观的异步编程并非不可实现。

结论

是时候重新审视async/await的设计了。或许我们并不需要它,甚至应该彻底抛弃它。编程世界的未来,不应该被这种模式所束缚。

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/1961.html

标签: aysnc
分享给朋友:

“对异步编程的重新思考:Async/Await是否真的是解决方案?” 的相关文章

vue:组件中之间的传值

一、父子组件之间的传值----props/$emit1、父组件向子组件传值--props2.子组件想父组件传值-this.$emit('select',item)二、父组件向下(深层)子组件传值----provide/injectprovide:Object | () => O...

GitLab-合并请求

描述合并请求可用于在您对项目进行的其他人员之间交换代码,并轻松与他们讨论更改。合并请求的步骤步骤1-在创建新的合并请求之前,GitLab中应该有一个创建的分支。您可以参考本章来创建分支-步骤2-登录到您的GitLab帐户,然后转到“ 项目”部分下的项目 -步骤3-单击“ 合并请求”选项卡,然后单击“...

Java教程:gitlab-使用入门

1 导读本教程主要讲解了GitLab在项目的环境搭建和基本的使用,可以帮助大家在企业中能够自主搭建GitLab服务,并且可以GitLab中的组、权限、项目自主操作GitLab简介GitLab环境搭建GitLab基本使用(组、权限、用户、项目)2 GitLab简介GitLab是整个DevOps生命周期...

高效使用 Vim 编辑器的 10 个技巧

在 Reverb,我们使用 MacVim 来标准化开发环境,使配对更容易,并提高效率。当我开始使用 Reverb 时,我以前从未使用过 Vim。我花了几个星期才开始感到舒服,但如果没有这样的提示,可能需要几个月的时间。这里有十个技巧可以帮助你在学习使用 Vim 时提高效率。1. 通过提高按键重复率来...

我的VIM配置

写一篇关于VIM配置的文章,记录下自己的VIM配置,力求简洁实用。VIM的配置保存在文件~/.vimrc中(Windows下是C:\Users\yourname \_vimrc)。VIM除了自身可配置项外,还可插件扩展。VIM的插件一般用vundle或vim-plug来管理,但我力求简单,不打算装太...

30 个纯 HTML5 实现的游戏

浏览器和 JavaScript 的功能逐年不断的变强变大。曾几何时,任何类型的游戏都需要Flash。但随着 HTML5 发展,HTML5 + WebGL 游戏式就慢慢占领着这个舞台。以下是30款流行的游戏,它们可以在所有现代浏览器中运行,并且只使用web技术构建。1. HexGL地址:http://...