【问题标题】:How to merge multiple effects in Elm?如何在 Elm 中合并多个效果?
【发布时间】:2017-07-30 02:10:21
【问题描述】:

我有一个关于合并多个效果的问题。我的目标是并行运行 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 年的答案是否定的)。

【问题讨论】:

    标签: parallel-processing elm


    【解决方案1】:

    使用 Elm 架构,您可以使用 Cmd.batch 一次启动一堆任务,但是当结果准备好时,它们将在更新函数中以单个 Msg 值的形式出现,并且没有保证的顺序.

    因此,(至少从 Elm 0.18 开始),您需要自己处理“合并”结果,因为您触发的 Msgs 将一一出现。在您的 Dice 示例中,您需要一个 Msg 构造函数来在特定数组索引处设置骰子值(在此示例中,我使用 Array 而不是 List,因为您将通过索引设置很多):

    type Msg
        = Roll
        | NewFaceAt Int Int
    

    现在您只需在 update 案例中处理 NewFaceAt 构造函数:

    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 请求时效果更明显)。

    【讨论】:

      【解决方案2】:

      Process.spawn 将允许您启动运行时可能交错的多个任务,但是似乎没有办法以单个 Msg a 结束,其中 a 是一些组合多个并行任务的结果。

      Future Plans 下“流程”页面上的注释似乎与您的问题相关。

      如果您想进一步探索现在的可能性以及spawn 的行为,我创建了一个extension of the more-cats HTTP example app,从elm-task-extra 移植了一些助手(0.18 尚未更新) .

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多