Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 道具更改时如何取消Cmd.OfAsync?_F#_Elmish - Fatal编程技术网

F# 道具更改时如何取消Cmd.OfAsync?

F# 道具更改时如何取消Cmd.OfAsync?,f#,elmish,F#,Elmish,假设我有一个受控的Elmish表单: 类型模型= { 查询:字符串 孤岛加载:bool 结果:结果选项 } 类型消息= |字符串更新 |收到结果 让更新消息模型= 将消息与匹配 |UpdateQuery-> 让我们来看看下一个模型= { 模仿 查询=查询 IsLoading=true } 设cmd= Cmd.OfAsync.result(异步{ let!results=Api.tryFetchQueryResults查询 返回ReceivedResults结果 }) nextModel,cmd

假设我有一个受控的Elmish表单:

类型模型=
{
查询:字符串
孤岛加载: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