Elixir:如何避免深入嵌套的case语句?
假设我有一个函数Elixir:如何避免深入嵌套的case语句?,elixir,Elixir,假设我有一个函数main_function,它依赖于其他三个函数的结果,每个函数可以返回{:ok,result}或{:error,error}。我怎样才能避免在javascript中有像回调地狱一样的深度嵌套的case语句呢 例如: def func1(input) do case SOMECONDITION do {:ok, result} -> {:ok, result} {:error, error} -> {:error, erro
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
这感觉不太对劲…[Edit]:我在一篇精彩的演讲中添加了一个方便的链接,介绍了这一概念,以及下面ElixirConf 2018针对更复杂需求的解决方案。 别担心,长生不老药已经覆盖了你。您需要:
和/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
额外资源:
以下是《信条》作者关于这一概念的精彩演讲,由ElixirConf 2018提供:
下面是一篇关于
的很棒的帖子,其中有/1
:回答了对公认答案的评论:
这是一个有趣的方法。但是假设
func1
和func2
正在向数据库写入数据。如果func1
返回错误,我根本不希望执行func2
。会是这样吗
如果您使用的是exto,还有另一个选项
假设func1
、func2
和func3
都写入数据库,但步骤在func2
处失败,这意味着func1
已经写入数据库
假设它们返回{:ok,result}
或{:error,error}
救命啊
alias-exto.Multi
别名MyApp.Repo
def主功能(输入)do
结果=
Multi.new()
|>Multi.run(:result1,fn\u1->func1(输入)结束)
|>Multi.run(:result2和func2(&1.result1))
|>Multi.run(:result3和func3(&1.result2))
|>回购交易()
案例结果如何
{:好,%{result1:u,result2:u,result3:}}->
{:好的,预期结果}
{:error,error,{u changes}->
{:错误,错误}
结束
结束
对于Multi,返回错误元组将中止任何进一步的操作,并使整个Multi失败。另外,由于它使用的是事务,任何成功的都将回滚。我认为您可以使用
和
语句。这是一个有趣的方法。但是假设func1
和func2
正在向数据库写入数据。如果func1
返回错误,我根本不希望执行func2
。会是这样吗?这样就可以了!它在第一次不匹配时停止执行,因此在这种情况下,第一个错误-因此如果func1不成功,func2将不会尝试执行。不要忘记else
子句,非常有用!
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