我有一个关于合并多个效果的问题。我的目标是并行运行N个命令(例如Random或Http),然后合并结果并启动更新。可以认为它是N骰子Elm Architecture Dice exercises的延伸。
我知道您可以使用Task.map2
或Task.sequence
执行此操作,但我正在专门寻找并行执行。
Cmd.batch
听起来像我想要的并行部分,但我无法弄清楚如何合并执行的结果。
这是my full Elm code 这里how I'm guessing at transforming it to act in parallel(没有工作)。
对于它的价值,在JS中我用Promise.all
Promise.all([promise1, promise2, …]).then(resultsList => …)
在此主题上找不到任何关于此主题的内容,除此之外,它回避了问题:How to perform multiple Http requests (Tasks) in bulk in Elm lang,这避免了多重影响:How do I add a second die to this elm effects example?。希望情况仍然如此:Is there parallelism in Elm?(2015年答案为否)。
答案 0 :(得分:1)
Process.spawn将允许您启动运行时可能交错的多个任务,但是似乎没有办法以单Msg a
结尾{{{ 1}}是一些并行任务的综合结果。
Future Plans下的处理页面上的注释似乎与您的问题相关。
如果您想进一步探索现在可能发生的事情以及a
的行为,我已经创建了一个extension of the more-cats HTTP example app,从{移植{@ 3}}中的一些助手{3}}(尚未更新0.18)。
答案 1 :(得分:1)
使用Elm Architecture,您可以使用Cmd.batch
一次启动一系列任务,但是当结果准备就绪时,它们将在更新函数中以单Msg
个值的形式出现,并且没有保证的顺序。
因此,(至少从榆木0.18开始),你需要自己处理“合并”结果,因为你发射的Msgs
将逐一进入。在你的骰子示例中,您需要一个Msg
构造函数来设置特定数组索引处的骰子值(在此示例中,我使用Array
而不是List
,因为您将设置很多索引):
type Msg
= Roll
| NewFaceAt Int Int
现在您只需处理NewFaceAt
案例中的update
构造函数:
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Roll ->
( model
, Cmd.batch
(Array.toIndexedList model.dice
|> List.map (\( i, _ ) -> Random.generate (NewFaceAt i) (Random.int 1 6))
)
)
NewFaceAt index newFace ->
( { model | dice = Array.set index newFace model.dice }, Cmd.none )
Here is a working example of the above on ellie-app.com
如果您想更接近Promise.all([...]).then(...)
示例,则必须在模型上烘焙某种状态标记,每次收到NewFaceAt
时都会更新。例如,您的骰子可能是Maybe Int
的列表,然后当您滚动时,将它们全部设置为Nothing
,并且当骰子值进入时,您将它们设置为Just value
然后检查查看是否填写了所有骰子值。您可以编写视图,以便在结果仍未知时显示“加载”消息,并且仅在所有结果都显示时显示图像。Here is an example that waits until all results are ready(授予,它发生得如此之快以至于您赢了看不到加载屏幕;处理多个Http请求时效果更明显。)