f# - 如何在道具更改时取消 Cmd.OfAsync?
问题描述
假设我有一个受控的 Elmish 形式:
type Model =
{
Query : string
IsLoading : bool
Result : Result<QueryResults, string> option
}
type Message =
| UpdateQuery of string
| ReceivedResults of Result<QueryResults, string>
let update message model =
match message with
| UpdateQuery query ->
let nextModel =
{
model with
Query = query
IsLoading = true
}
let cmd =
Cmd.OfAsync.result (async {
let! results = Api.tryFetchQueryResults query
return ReceivedResults results
})
nextModel, cmd
| ReceivedResults results ->
{
model with
IsLoading = false
Results = Some results
}, Cmd.none
每次model.Query
更改时,它都会发送一个async
请求。但是,如果已经有一个请求正在进行中,我希望将其取消并替换为新请求。
在 Elmish 中执行此操作的好方法是什么?
解决方案
没有内置支持取消基础XMLHttpRequest
.
但是,我们可以构建一些支持类似取消功能的小型机器:
首先,Model
使用有关当前待处理查询的信息来增加您的信息,并Message
使用该查询的链接(一个简单的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>
update
接下来,在您的函数中提供这些数据
| UpdateQuery query ->
let correlationId = Guid.NewGuid()
let nextModel =
{
model with
Query = query
IsLoading = true
PendingQuery = Some correlationId
}
let cmd =
Cmd.OfAsync.result (async {
let! results = Api.tryFetchQueryResults query
return ReceivedResults (correlationId, results)
})
nextModel, cmd
最后,在从服务器接收数据时检查未决查询并忽略与链接不匹配的内容
| 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
推荐阅读
- python - 与 mmap 共享对象?
- swift - 重新加载时 UICollectionViewCell 错误的高度
- php - 转换日期格式 1542575966120 18/11/2018
- html - html拖放不同的项目
- python - 在循环中使用 TensorFlow Estimator
- qt - 如何设置 Qml 文本项的行距?
- python-3.x - pygame - 如何读取文件并将文本blit到屏幕上
- angular - 在角度问题中使用 Bootstrap 进行无限滚动
- hyperlink - Netlogo:如何向每个链接的邻居提问
- unity3d - 在 Unity 中使用 uFllex 找不到 DLL 错误