我想同时执行多个任务。在Javascript中,我会:
async function cook_an_egg() {}
async function take_shower() {}
async function call_mum() {}
await Promise.all([cook_an_egg(), take_shower(), call_mum()])
如何在Elixir任务模块中实现Promise.all
?从文档中看,似乎只能实现await
1个任务;在每个task
内定义1个函数;并且仅将相同的函数应用于具有async_stream
的多个项。
3条答案
按热度按时间np8igboo1#
适用于Elixir v1.11.0及更高版本
Task.await_many
的设计就是为了完成这个任务。它正确地处理了整个超时,并且在遇到退出、超时等情况时,应该做最不令人惊讶的事情。对于旧版本
Task.yield_many
是一个比Task.await
更安全的解决方案。不幸的是,它有点冗长,因为它让我们自己负责处理超时和死任务。如果我们想模仿async
/await
的行为,并在出错时退出,它将如下所示:为什么不使用
await
?使用
Task.await
可以在简单的情况下工作,但是如果你关心超时,你可能会给自己带来麻烦。列表中的Map是顺序发生的,这意味着每个Task.await
在给出结果之前都会阻塞指定的超时时间,此时我们移动到列表中的下一个项目,并 * 再次 * 阻塞,直到完全超时。我们可以通过创建一个睡眠时间为1-8秒的任务列表来演示这种行为。在默认的超时时间为5秒的情况下,当直接使用
await
调用这些任务时,其中一些任务会被杀死,但是当我们枚举列表时,情况并不是这样的:如果我们修改它以使用
Task.yield_many
,我们可以得到所需的行为:gg58donl2#
可以将
await
函数Map到任务引用列表。vqlkdk9b3#
Since this question was asked, Elixir's Task module has sprouted new powers.
There is both
Task.await_many/2
andTask.yield_many/2
, which do what they sound like.To answer the example in the original question:
There is no analog to
Promise.any
, but you could write one pretty easily usingTask.yield_many/2