【问题标题】:Break process in case of fail失败时中断进程
【发布时间】:2020-12-30 22:32:19
【问题描述】:

我正在 elixir 中开发一个 API,并且我有一个进程连续执行 6 个操作。我的问题是,如果这 6 个操作中的任何一个操作失败,我该如何中断此执行?

我不想级联成多个案例块。

其实我想要“回归”之类的东西。

有人对此有好的解决方案吗?

【问题讨论】:

  • 您能出示此代码或具有代表性的等效代码吗?

标签: elixir


【解决方案1】:

当 Elixir 中有一系列连续的条件(例如多个 case 块)时,with 子句(语句?运算符?)会很有用。

Elixir docs中有一个例子。

像这样比较一堆臭烘烘的嵌套 case 语句:

case op1(x) do
  {:ok, result1} -> 
     case op2(result1) do
        {:ok, result2} -> 
            case op3(result2) do
               {:ok, result3} -> {:ok, result3}
               {:error, error} -> {:error, error}      
            end
        {:error, error} -> {:error, error}      
     end   
  {:error, error} -> {:error, error}      
end

真的很难理解,而且感觉是多余的。基本上,我们希望继续深入研究顺序操作 1、2 和 3,否则会出现错误退出。

我们可以使用with语法重写上面的内容——密切注意箭头的方向!

with {:ok, result1} <- op1(x),
     {:ok, result2} <- op2(result1) do
  op3(result3)
else
  {:error, error} -> {:error, error}
end

您使用逗号分隔一个又一个操作,最终形成一个do 块,您可以在其中执行最终操作。

如果任何操作失败,可以将执行路由到可选的else 块中进行匹配——如果您需要区分不同的返回值(例如,如果需要特定的日志记录),这将非常有用,否则else 块是多余的,通常可以省略。

了解with 块是编写更简洁的Elixir 代码的一大步。使用 with 语法的替代方法可以是编写多个函数签名来处理每个步骤的输出,但这感觉像是很多忙碌的工作,并不总是合理的。

【讨论】:

  • else {:error, error} -&gt; {:error, error} 形式的块是完全多余的。 {:error, error} 将在没有它的情况下从 with/1 返回,一旦遇到。
  • 你是对的,当然——我已经更新了解释。我发现以else 块为例很有帮助,但是,如果您确实需要匹配不同的返回值。
【解决方案2】:

在长生不老药中没有返回选项真的让我有一段时间心烦意乱。我建议你拥抱模式匹配。我知道这似乎不正确,但您最终会意识到它背后的简单性。你可以不用嵌套,只需为你期望的每个模式创建一个新函数。

这是一个 sn-p,我基本上在 self() 上递归

  ...

  def handle_cast({:get_name, port, container}, state) do
    app_name = Map.get(container, "Labels") |> Map.get("app")
    GenServer.cast(self(), {:domain_map, app_name, port, container})
    {:noreply, state}
  end

  def handle_cast({:containers, containers}, state) do
    Enum.map(containers, fn container ->
      GenServer.cast(self(), {:container, container})
    end)

    {:noreply, state}
  end

  def handle_cast({:container, container}, state) do
    Enum.map(Map.get(container, "Ports"), fn port ->
      GenServer.cast(self(), {:get_name, port, container})
    end)

    {:noreply, state}
  end

 ...

如果模式不匹配,那基本上就是你的 return 语句。

【讨论】:

    猜你喜欢
    • 2015-10-21
    • 1970-01-01
    • 2016-08-25
    • 1970-01-01
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    相关资源
    最近更新 更多