【问题标题】:What's the canonical way to handle asynchronous work in Erlang?在 Erlang 中处理异步工作的规范方法是什么?
【发布时间】:2016-08-08 05:53:04
【问题描述】:

我有 JavaScript 方面的经验,我习惯于回调函数:

function myFun(arg1, arg2, successCB, failCB) {
  var sum = arg1 + arg2;
  if (sum > tooHigh) {
    failCB("too high!");
  } else {
    otherFun(sum, arg1, successCB, failCB);
  }
}

我可以用 Erlang 编写相同的代码:

my_fun(Arg1, Arg2, SuccessCB, FailCB) ->
  case Arg1 + Arg2 of
    Sum when Sum > ?TOO_HIGH ->
      FailCB(too_high);
    Sum ->
      other_fun(Sum, Arg1, SuccessCB, FailCB)
  end.

根据我的经验,我认为这种方法是合理的,但我觉得我需要在我的代码中做很多这样的事情,所以,显然,有更好的方法来管理这些真/假/任何场景。

这是典型的 Erlang 代码吗?还有其他方法可以让我这样做吗?

【问题讨论】:

  • 为什么不直接使用不同的函数子句呢?还是case User of
  • 您需要做好功课,因为如果您尝试在 Erlang 中使用与在其他语言中相同的方法来处理错误,那么您做错了。例如,尝试搜索 Erlang 的“让它崩溃”哲学,以及 here's a related question

标签: erlang


【解决方案1】:

JavaScript 使用回调是因为您只有一个线程,而回调是您跨上下文切换传输状态的方式。

回调函数是一种普遍有用的工具,但在 JavaScript 中它们是一个基本工具,因为它是异步工​​作的完成方式。

在 Erlang 中,您可以(而且应该!)使用许多进程。在单个进程中,您可以进行同步的阻塞调用,因为这不会影响系统性能。

我希望上面 JS 代码的 Erlang 版本看起来像

my_fun(Arg1, Arg2) ->
  case Arg1 + Arg2 of
    Sum when Sum > ?TOO_HIGH ->
      too_high;
    Sum ->
      other_fun(Sum, Arg1)
  end.

没有回调,因为函数返回值(too_high 可能还有{ok, Result})。所有函数都被阻塞了——如果other_fun 是一个网络调用,它可能会等待几秒钟才能返回。如果需要并行性,您可以spawn 任意数量的进程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多