Опубликовать процесс Enum.to_list - PullRequest
0 голосов
/ 09 октября 2018

У меня есть этот конвейер

 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 голосов
/ 09 октября 2018

Главное, что здесь необходимо принять во внимание: задачи могут потерпеть неудачу.Если желаемое поведение - просто отбросить их, просто используйте пример непосредственно из примера 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 s.

0 голосов
/ 09 октября 2018

Другой способ:

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

предупреждение : поскольку мы напрямую обращаемся ко второму элементу кортежа, возвращаемого каждым Task, проверка на наличие Task не производится.был правильно запущен.Вы можете добавить сопоставление с шаблоном в :ok, чтобы исправить эту проблему (как вы сделали в вопросе).

...