7

在过去的 1 年里,我正在研究 Java 和 flex。在编写 flex 代码时,我的大部分代码部分都因异步而折腾。这让我想到了同步执行语言与异步执行语言的真正优点和缺点。

与其他相比,它们在哪些领域更强大,它们在哪些领域下降?

4

3 回答 3

8

去年的大部分时间我都在 Silverlight 中进行编码,这意味着我花了很多时间思考(并解决)您所描述的相同问题。

简而言之,正如其他人所指出的那样,异步模型的真正优势在于它能够创建与现实世界良好互操作的健壮系统。如果每次 Web 服务调用需要几秒钟才能返回 UI 线程就会停止,那么没有人可以真正使用 Silverlight(或 Flash)应用程序。

最大的缺点是生成的代码复杂且难以排除故障。像错误处理这样的事情是一个 PITA,但我不得不处理的最烦人的事情是协调来自多个异步调用的响应。例如,如果您在调用 B 之前需要调用 A 的信息,并且在调用 C 之前需要调用 B 的信息(等等),那么生成的代码看起来真的很不愉快,并且容易受到各种奇怪的副作用的影响. 有一些技术可以使所有这些东西工作,甚至相当干净,但如果你来自同步世界(就像我一样),这是一个重要的学习曲线。(在我看来,微软在回调时将事件推送为处理 WCF 调用的方式也无济于事,

(是的,其他人说它不是异步的语言是正确的,因为特定的框架需要以异步方式构建你的代码——但我明白你的意思。)

更新 2014.09.23 -

自从我写了上面的答案以来,我已经用各种异步框架做了很多工作(可能其他所有做过 Web 编码的人也是如此),并认为我会添加一些额外的随机注释:

  • 如果您使用的是具有一流异步支持的 C# 或 F# 之类的语言,那么至少在您了解奇怪的async/await模式后,其中的大部分内容会变得容易得多。能够轻松地循环异步调用,并用一个简单的 包裹整个事情,try/catch如果你曾经不得不用旧的方式来做这件事,那就太棒了。

  • 如果您没有使用具有一流异步支持的语言,请开始使用该语言确实提供的任何promisefuture或支持(例如,JQuery's或 Angular's 。与通常通过回调获得的相比,它们更简洁并提供更好的结构.task$.Deferred()$q.defer()

  • 异步代码对于编写可扩展的服务器端系统至关重要。使典型的 Web 服务器能够很好地扩展的最大问题之一是它开始用尽线程,至少,如果它专门使用一个线程来处理传入的请求,它就会出现这种情况。如果该线程停止,因为它正在等待长时间运行的同步调用完成,则它完全无法帮助解决其他任何问题。更好的是使您的 Web 服务器代码异步,这样当您等待 DB 调用返回时,该线程可以在 DB 运行并执行 DB 所做的任何事情时为六个其他请求提供服务。在这一点上,对于高度可扩展的系统,异步是唯一的游戏。(只要问任何 Node 爱好者。)

于 2009-12-18T19:49:47.720 回答
3

(撇开语义级别的讨论,即“同步/异步语言”)

建立在“语言”(无论它是什么)上的“框架”应该能够处理这种情况(同步/异步程序流)以便有用(阅读:$ wise)。

异步习语适用于各种规模。

在大规模情况下,异步技术有助于构建可靠的系统,因为现实世界本质上是异步的。换句话说,一个人需要以“异步思维”来思考,以应对诸如失败、损失、延误等现实生活中的情况。

即使在较小的规模上(例如 GUI 应用程序),事件(例如“鼠标点击”)也往往是“异步的”。当然,它们在某些时候是“序列化”的(以便运行某些软件的应用程序可以处理),但这并没有改变事件(可能)与相关程序的流程“异步”发生的事实.

于 2009-12-18T19:32:23.203 回答
1

我认为这与语言无关,而与框架有关。

反例:

当用 C(如果有的话,是一种“同步”语言)编写“经典 Mac”(MacOS 9 及更早版本)应用程序时,您没有抢占式多线程,因此所有可能阻塞的系统调用都有一个异步对应项,您可以在其中填充带有参数的数据块,包括回调函数。然后你进行系统调用(它会立即返回),你的回调将被异步调用(在所谓的“中断级别”中)。回调会执行另一个异步系统调用,创建一个与主线程异步运行的长后台线程并不少见。

于 2009-12-18T19:34:21.483 回答