发布流程Enum.to_list

时间:2018-10-09 08:01:06

标签: elixir

我有这个管道

 events
 |> Task.async_stream(&expensive_func/1)
 |> Enum.to_list

哪个返回此数据:

[ok: {item}, ok: {item} ... ]

所以,为了只包含一组项目,[item, item]我将其像这样进行后期处理:

 events
 |> Task.async_stream(&expensive_func/1)
 |> Enum.to_list
 |> Enum.map(fn {:ok, event} -> event end)

有没有更优雅的方式做到这一点?

2 个答案:

答案 0 :(得分:2)

另一种方式:

events
|> Task.async_stream(&expensive_func/1))
|> Enum.map(&(elem(&1,1)))

警告:由于我们直接访问每个Task返回的元组的第二个元素,因此不会进行检查以确保Task已正确运行。您可以在:ok上添加匹配的模式来解决该问题(如您在问题中所做的那样)。

答案 1 :(得分:2)

这里要考虑的主要事情是:任务可能会失败。如果想要的行为只是丢弃它们,只需直接使用Task.async_stream/3示例中的示例,然后明确丢弃它们

events
|> Task.async_stream(&expensive_func/1)
|> Enum.reduce([], fn
  {:ok, event}, acc -> [event | acc]
  _, acc -> acc # discard failures
end)
|> Enum.reverse()

另一种选择是依靠任务的返回值(如果失败则返回例如nil),则可能直接使用Keyword.values/1

events
|> Task.async_stream(&expensive_func/1)
|> Enum.to_list()
|> Keyword.values()

FWIW,如果至少有一项任务因您的函数无法处理MatchError而失败,那么您的原始解决方案将引发:error