2017-10-15 60 views
2

我有一個函數ping(),導致{:ok}{:error}Elixir/Phoenix多次嘗試函數,捕捉:ok

是否有可能使一個包裝功能部件test(),將嘗試ping() 5倍,返回一個錯誤之前,除非這些ping()之一,{:ok}迴應?

如果test()可以從ping()第一次嘗試返回{:ok},那麼它應該退出遞歸,但如果沒有,則繼續嘗試ping()另外4次。

我檢查了try/catch,但似乎無法確定如何使其工作。任何提示讚賞!

回答

3

這裏不需要try/catch。用case聲明匹配響應一個簡單的遞歸函數就足夠了:

defmodule A do 
    # A function that returns `{:ok}` a third of the times it's called. 
    def ping, do: if :random.uniform(3) == 1, do: {:ok}, else: {:error} 

    # 5 attempts. 
    def test(), do: test(5) 

    # If 1 attempt is left, just return whatever `ping` returns. 
    def test(1), do: ping() 
    # If more than one attempts are left. 
    def test(n) do 
    # Print remaining attempts for debugging. 
    IO.inspect {n} 
    # Call `ping`. 
    case ping() do 
     # Return {:ok} if it succeeded. 
     {:ok} -> {:ok} 
     # Otherwise recurse with 1 less attempt remaining. 
     {:error} -> test(n - 1) 
    end 
    end 
end 

測試:

iex(1)> A.test 
{5} 
{4} 
{3} 
{2} 
{:ok} 
iex(2)> A.test 
{5} 
{4} 
{3} 
{2} 
{:error} 
iex(3)> A.test 
{5} 
{:ok} 
iex(4)> A.test 
{5} 
{:ok} 
iex(5)> A.test 
{5} 
{4} 
{:ok} 
+0

謝謝您的回答!正是我在找什麼。祝你今天愉快! – Ilya