我有一种情况需要同步发送两个post请求,第二个取决于第一个的响应,问题是第二个在第一个响应被分配之前发送,因此发送错误的信息:
update : msg -> model -> (model, Cmd msg)
update msg m =
case msg of
...
Submit -> (m,
send FirstResp <| post "/resource1"
(jsonBody <| encoderX m) int)
FirstResp (Ok x) -> ({m | pid = x},
send SecondResp <| post "/resource2"
(jsonBody <| encoderY m) int)
...
我测试了好几次。如果服务器在第一篇帖子中提供3
,则pid
会以0
的形式发送,但如果我再次提交,pid
将以3
的形式发送例如,服务器的答案4
将被忽略。
如何让帖子等待分配值?
答案 0 :(得分:4)
由于elm中的数据结构是不可变的,{m | pid = x}
不会更改m
但会返回新记录。因此,当您将其传递给第二个请求时,您没有更新的模型。
使用{m | pid = x}
两次会得到你想要的结果(但它不是很漂亮)
FirstResp (Ok x) -> ({m | pid = x},
send SecondResp <| post "/resource2"
(jsonBody <| encoderY {m | pid = x}) int)
在发送请求之前,您可以使用let in
将新模型存储在变量中。如果您现在修改模型,您只需要在一个地方查看。
FirstResp (Ok x) ->
let
newM = {m | pid = x}
in
(newM, send SecondResp <| post "/resource2"
(jsonBody <| encoderY newM) int)
如果您不需要模型中第一个请求的结果,则更好的解决方案是将请求与Task.andThen
链接起来。有了这个,你不需要2个单独的消息(FirstResp,SecondResp)。
request1 m =
post "/resource1" (jsonBody <| encoderX m) int)
|> Http.toTask
request2 m =
post "/resource1" (jsonBody <| encoderX m) int)
|> Http.toTask
Submit ->
( m
, request1 m
|> Task.andThen request2
|> Task.attempt Resp
)
Resp (Ok res2) ->
-- res2 is the result of your request2
如果您需要两个结果,您可以将它们映射到元组并在更新函数中提取它。
Submit ->
( m
, request1 m
|> Task.andThen
(\res1 -> request2 res1
|> Task.map ((,) res1)
)
|> Task.attempt Resp
)
Resp (Ok (res1, res2) ->
-- use res1 and res2