有了这段代码,我希望让孩子对给定的 number_list 执行 is_prime 函数并返回结果,但我在从 Task.await 方法检索结果时遇到问题。
defmodule LeaderWorker do
def start() do
children = [{Task.Supervisor,
name: Task.SomeThingSupervisor,
}]
Supervisor.start_link(children, strategy: :one_for_one)
end
def run(number_list, num_workers) do
results =
number_list
|> Task.async_stream(&check_prime/1, max_concurrency: num_workers)
|> Enum.map(&Task.await/1)
IO.inspect(results)
end
def check_prime(number) do
prime = is_prime(number)
IO.inspect({number, prime})
{number, prime}
end
def is_prime(number) when number <= 1 do
false
end
def is_prime(number) do
not Enum.any?(2..(div(number, 2)), &(&1 != 1 and rem(number, &1) == 0))
end
end
LeaderWorker.start()
number_list = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
LeaderWorker.run(number_list, 4)
这是我遇到的错误:
elixir .\clean.ex
{2, false}
{3, true}
{4, false}
{5, true}
** (FunctionClauseError) no function clause matching in Task.await/2
The following arguments were given to Task.await/2:
# 1
{:ok, {2, false}}
# 2
5000
Attempted function clauses (showing 1 out of 1):
def await(%Task{ref: ref, owner: owner} = task, timeout) when timeout == :infinity or is_integer(timeout) and timeout >= 0
(elixir 1.16.2) Task.await/2
(elixir 1.16.2) lib/enum.ex:1708: anonymous fn/3 in Enum.map/2
(elixir 1.16.2) lib/enum.ex:4396: anonymous fn/3 in Enum.map/2
(elixir 1.16.2) lib/task/supervised.ex:386: Task.Supervised.stream_deliver/7
(elixir 1.16.2) lib/enum.ex:4396: Enum.map/2
clean.ex:14: LeaderWorker.run/2
clean.ex:36: (file)
我正在尝试找到该问题的解决方案,以获得我应该拥有的 {number, boolean} 列表
您可以像这样重写您的
run
函数:
def run(number_list, num_workers) do
stream =
number_list
|> Task.async_stream(&check_prime/1, max_concurrency: num_workers)
Enum.reduce(stream, %{}, fn {number, prime}, acc -> Map.put(acc, number, prime) end)
end
由于您使用的是流,因此您需要以某种方式收集项目,而不是简单地等待结果,
reduce
这里可以解决问题,但如果我错了,请有人纠正我:)
进行此更改后,您将得到以下结果作为输出:
{2, false}
{3, true}
{5, true}
{4, false}
{6, false}
{7, true}
{8, false}
{9, false}
{10, false}
{11, true}