如何链接命令消息

how to chain Cmd Msgs

我有一个 Cmd Msg 的列表,需要按顺序 运行。我目前正在使用 Cmd.batch list,但似乎所有这些都在同时 运行,因此以后应该 运行 的命令不知道早期命令应该对模型进行的任何更改.

我正在研究 Task.andThen,但不太确定这是否是正确的方向或如何从 Task 中创建 Cmd Msg。我是在正确的轨道上还是有更好的方法来做到这一点,也许仍然利用 Cmd.batch ?

我目前有两个函数 receive : String -> Model -> Cmd MsgprocessMsg : String -> Model -> Cmd Msg:

receive : String -> Model -> Cmd Msg
receive msg model =
  msg |> String.split "&"
      |> List.map String.trim
      |> List.sort
      |> List.map (processMsg model)
      |> Cmd.batch

processMsg : String -> Model -> Cmd Msg
...  (uses Cmd.Extra.message for Msg -> Cmd Msg)

编辑

edit2:我想我可以通过省略我在 receive/processMsg 中使用模型来简化示例,但我意识到我需要新模型才能形成每个后续消息。

我正在尝试使用 Task.sequenceTask.process 但没有成功。我可以成功获得 运行 的第一个命令,但我不知道如何扩展它以获得 运行:

的所有命令
receive : String -> Model -> Cmd Msg
receive msg model =
    let 
        msgs = 
            msg |> String.split "&" 
                |> List.map String.trim
                |> List.sort
                |> List.head
                |> Maybe.withDefault "none"
                |> Task.succeed
    in
        Task.perform Oops (processMsg model) msgs

processMsg : String -> Model -> Msg
...

我考虑过将 processMsg 更改为 processMsg : String -> Task String Msg,但后来我不知道为 Task.perform 的第二个参数提供什么。我不确定 Task.sequence 是如何计算的,因为当我尝试将它插入管道时,我最终得到的是

List (Task x String) -> Task x (List String) -> Task x (List Msg) -> Cmd (List Msg)

我不知道该怎么办。

Task.sequence 将确保任务 运行 按顺序而不是同时进行。

要从任务中创建 Cmd msg,您可以使用 Task.attempt or Task.perform

编辑

根据您更新后的问题,我认为没有必要为此使用 Tasks。听起来您想将一堆更新链接在一起,这可以通过让 update 函数递归调用自身来完成。您可以使用 List.foldl 为每个后续消息累积模型状态和命令。

这是我的意思的一个简单粗暴的例子:

update msg model =
  case msg of
    ChainMsgs msgs ->
      let
        chain msg1 (model1, cmds) =
          let (model2, cmds1) = update msg1 model1
          in model2 ! [ cmds, cmds1 ]
      in
        List.foldl chain (model ! []) msgs
    _ ->
      { model | message = model.message ++ ", " ++ toString msg } ! []

您保证消息以正确的顺序传递给 update,因为没有必要将其包装在使执行顺序不明确的任务中。

这是一个gist of this quick 'n dirty example which you can paste directly into http://elm-lang.org/try