#f# #elmish
#f# #elmish
Вопрос:
Предположим, у меня есть управляемая форма 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?
Ответ №1:
Нет ничего встроенного для поддержки отмены базового 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
Комментарии:
1. Это игнорирует «устаревшие» запросы, но как мне их отменить?
2. Чтобы отменить, вам нужно получить доступ к базовому XMLHttpRequest и вызвать abort() для этого. Но запрос XMLHttpRequest не отображается в Fable. Удаленный API.
3. У меня есть доступ к cancellation via
Async.StartAsPromise
, который принимает токен отмены. Мой вопрос в том, как я должен интегрировать / отслеживать токен отмены с Elmish