F# 道具更改时如何取消Cmd.OfAsync?
假设我有一个受控的Elmish表单:F# 道具更改时如何取消Cmd.OfAsync?,f#,elmish,F#,Elmish,假设我有一个受控的Elmish表单: 类型模型= { 查询:字符串 孤岛加载:bool 结果:结果选项 } 类型消息= |字符串更新 |收到结果 让更新消息模型= 将消息与匹配 |UpdateQuery-> 让我们来看看下一个模型= { 模仿 查询=查询 IsLoading=true } 设cmd= Cmd.OfAsync.result(异步{ let!results=Api.tryFetchQueryResults查询 返回ReceivedResults结果 }) nextModel,cmd
类型模型=
{
查询:字符串
孤岛加载:bool
结果:结果选项
}
类型消息=
|字符串更新
|收到结果
让更新消息模型=
将消息与匹配
|UpdateQuery->
让我们来看看下一个模型=
{
模仿
查询=查询
IsLoading=true
}
设cmd=
Cmd.OfAsync.result(异步{
let!results=Api.tryFetchQueryResults查询
返回ReceivedResults结果
})
nextModel,cmd
|接收结果结果->
{
模仿
IsLoading=错误
结果=一些结果
},Cmd.none
每次model.Query
更改时,它都会发出async
请求。但是,如果已经有一个正在进行的请求,我希望该请求被取消并替换为新的请求
在Elmish中,有什么好方法可以做到这一点?没有内置任何东西支持取消底层的
XMLHttpRequest
但是,我们可以构建一些小型机械,以支持取消功能:
首先,使用有关当前挂起查询的信息扩充您的模型
,并使用指向该查询的链接(简单的Guid
即可)扩充您的消息
open System
type Model =
{
Query : string
IsLoading : bool
Result : Result<QueryResults, string> option
PendingQuery: Guid option
}
type Message =
| UpdateQuery of string
| ReceivedResults of Guid * Result<QueryResults, string>
最后,在从服务器接收数据时检查挂起的查询,并忽略与链接不匹配的内容
| ReceivedResults (correlationId, results) ->
match model.PendingQuery with
| Some id when id = correlationId ->
{
model with
IsLoading = false
PendingQuery = None
Result = Some results
}, Cmd.none
| _ -> model, Cmd.none
这会忽略“过时”请求,但如何实际取消它们呢?要取消,您需要获得底层XMLHttpRequest,并对其调用abort()。但是XMLHttpRequest并不是通过Fable.Remoting API出现的。我可以通过
Async.StartAsPromise
访问取消,它使用取消令牌。我的问题更多,我应该如何与Elmish集成/跟踪取消令牌
| ReceivedResults (correlationId, results) ->
match model.PendingQuery with
| Some id when id = correlationId ->
{
model with
IsLoading = false
PendingQuery = None
Result = Some results
}, Cmd.none
| _ -> model, Cmd.none