枚举如何与task.await一起使用



elixir Enum.map([Task.t], &Task.await)如何工作?

async_1 = Task.async(fn ->
  IO.inspect("done async 1") 
  1
end)
async_2 = Task.async(fn ->
  IO.inspect("done async 2")
  2
end)
results = Enum.map([async_1, async_2], fn(task) ->
  IO.inspect("starting new task")
  IO.inspect(task)
  Task.await(task) 
end)
IO.inspect(results)

从上面的代码中,我得到了IO日志:

"starting new task"
"done async 1"
"done async 2"
%Task{pid: #PID<0.51.0>, ref: #Reference<0.0.0.78>}
"starting new task"
%Task{pid: #PID<0.52.0>, ref: #Reference<0.0.0.79>}
[1, 2]
  1. 我希望第二个"starting new task"出现在"done async 2"之前。它如何热切地执行所有异步任务?
  2. 在文档中,它说await将"等待任务答复并返回"。我以为这意味着将暂停呼叫者进程,直到从Task进程发送终结消息为止。如果是这种情况,则应在每次map迭代中的Task.await(Task.t)调用中暂停,并且永远不会同时执行这些任务。日志证明我的假设是错误的。但是哪里错了?

这是我的repl http://elixirplayground.com?

Task.async不要等到Task.await运行传递的函数;它开始立即运行。在此处提供的任务的工作很小,因此当Enum.map有机会等待第二个任务时,它们都已经完成了。

感谢@dogbert的启蒙。我误解了elixir中的Task.async

它使我感到困惑,因为在ES7和C#中,async只是一个关键字,表明该功能将返回PromiseAsyncableasync仅被指控定义" Async_function"。await做两件事 - 执行并等待结果。即。

function async(action: fn): Promise
function await(async_action: Promise): ?Any { execute_and_wait(async_function) } 

在Elixir中,Task.async将在新过程中执行该功能,该过程类似于start_linkawait仅等待执行过程返回结果。

并不是说设计是不合理的。但是我更喜欢他们称其为async以外的其他东西,因为它打破了其他通用语言的惯例,因此更难学习。

最新更新