我有一个Cmd Msg需要按顺序运行的列表.我目前正在使用,Cmd.batch list但似乎所有这些都在同时运行,以至于稍后运行的命令不知道先前命令应该引入的模型的任何更改.
我正在调查Task.andThen但不太确定这是否是正确的方向或如何制造Cmd Msg出一个Task.我是在正确的轨道上还是有更好的方法来做到这一点,也许仍然有用Cmd.batch?
我现在有两个函数receive : String -> Model -> Cmd Msg和processMsg : 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)
Run Code Online (Sandbox Code Playgroud)
编辑
edit2:我想我可以通过省略我在receive/中使用模型来简化示例,processMsg但我意识到我需要新模型才能形成每个后续消息.
我正在尝试使用Task.sequence,Task.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
...
Run Code Online (Sandbox Code Playgroud)
我想改变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)
我不知道该怎么做.
Cha*_*ert 13
Task.sequence 将确保任务按顺序而不是同时运行.
要从Cmd msg任务中创建,您使用Task.attempt或Task.perform.
编辑
根据您更新的问题,我认为没有真正需要使用任务.听起来你想要将一堆更新链接在一起,这可以通过让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 } ! []
Run Code Online (Sandbox Code Playgroud)
您可以保证消息以update正确的顺序传递,因为不需要将它包装在使执行顺序模糊的任务中.
这是一个快速'n脏例子的要点,你可以直接粘贴到http://elm-lang.org/try: