失败时中断进程

Break process in case of fail

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

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

实际上我想要“return”之类的东西。

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

当你在 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

真的 很难理解,而且 {:error, error} -> {:error, error} 位感觉多余。基本上,我们只想继续钻取顺序操作(1、2、3、...)或退出并出错。

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

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

或更简洁地说,如果不需要特殊的错误处理,则省略 else 块:

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

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

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

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

没有 return 选项真的让我在 elixir 中困扰了一段时间。我建议你拥抱模式匹配。我知道这似乎不正确,但您最终会意识到其背后的简单性。你可以不用嵌套,只需要为你期望的每个模式创建一个新函数即可。

这是我基本上递归 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 语句。