假设我有一个函数main_function,它依赖于其他三个函数的结果,每个函数都可以返回{:ok, result}或者返回{:error, error}.如何避免在javascript中使用深度嵌套的case语句,感觉就像回调地狱一样.
例:
def func1(input) do
case SOMECONDITION do
{:ok, result} ->
{:ok, result}
{:error, error} ->
{:error, error}
end
end
def func2(input) do
case SOMECONDITION do
{:ok, result} ->
{:ok, result}
{:error, error} ->
{:error, error}
end
end
def func3(input) do
case SOMECONDITION do
{:ok, result} ->
{:ok, result}
{:error, error} ->
{:error, error}
end
end
def main_function(input) do
case func1(input) do
{:ok, result} ->
case func2(result) do
{:ok, result} ->
case func3(result) do
{:ok, result} ->
{:ok, EXPECTED_OUTCOME}
{:error, error} ->
{:error, error}
end
{:error, error} ->
{:error, error}
end
{:error, error} ->
{:error, error}
end
end
end
Run Code Online (Sandbox Code Playgroud)
这感觉不对......
The*_*sor 17
[编辑]:我已经为一个涵盖这个概念的精彩演讲添加了一个便利链接,以及来自下面ElixirConf 2018的更复杂需求的解决方案.
别担心 - Elixir让你满意.你想要这种特殊形式:with/1
with/1 当且仅当它们与预期结果匹配时才会继续执行函数.
你的主要功能基本上看起来像:
def main_function(input) do
with {:ok, result_1} <- func1(input),
{:ok, result_2} <- func2(result_1),
...,
do: {:ok, EXPECTED_OUTCOME}
end
Run Code Online (Sandbox Code Playgroud)
当它找不到匹配时,说因为有一个像{:error, _error}特殊形式的元组会返回遇到的第一个错误并停止执行这些函数.
您还可以添加其他条件.我使用过的一个例子是当用户可能期望某些操作需要完成许多功能时,我想提醒他们同样的事情,无论它在哪里失败:
def main_function(input) do
with {:ok, result_1} <- func1(input),
{:ok, result_2} <- func2(result_1),
... do
{:ok, EXPECTED_OUTCOME}
else
_error ->
{:error, "Couldn't complete action"}
end
end
Run Code Online (Sandbox Code Playgroud)
以下是来自Credo作者关于此概念的精彩演讲,由ElixirConf 2018提供:https://www.youtube.com/watch?v = ycpNi701aCs & t = 473s
这是一篇很棒的帖子with/1:https://www.erlang-solutions.com/blog/exploring-with-the-elixir-special-form.html