假设我们有一个文本输入字段,并且在其内容的每次更改时,我们都会向搜索API发送Http请求。现在,我们无法保证Http响应按照我们发送请求的顺序返回elm。
确保我们对与最新请求相对应的响应做出最简单的反应的最简单方法 - 而不是最新回复,这可能对应于过时的搜索字符串?是否有一种简单的方法将查询字符串附加到Elm的http效果返回的消息中?或者我们可以将响应链接到触发请求的任何其他方式?
如果可能,我希望避免将查询包含在搜索API的响应中。另一种解决方法是去除搜索,但这只会降低使用错误响应的可能性,而我们希望消除它。
感谢您的帮助!
示例:
import Html
import Html exposing (..)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode as Decode
main = Html.program
{ init = ( { searchText = "", result = "" }, Cmd.none )
, update = update
, subscriptions = (\model -> Sub.none)
, view = view
}
type alias Model =
{ searchText : String
, result: SearchResult
}
type alias SearchResult = String
type Msg
= NewSearchText String
| ReceivedResponse (Result Http.Error SearchResult)
update msg model =
case msg of
NewSearchText newText ->
( { model | searchText = newText}
, getSearchResult newText
)
ReceivedResponse (Result.Ok response) ->
( { model | result = response }
, Cmd.none
)
ReceivedResponse (Result.Err error) ->
Debug.crash <| (toString error)
getSearchResult : String -> Cmd Msg
getSearchResult query =
let
url = "http://thebackend.com/search?query=" ++ query
request : Http.Request SearchResult
request = Http.get url Decode.string
in
Http.send ReceivedResponse request
view model =
div []
[ Html.input [onInput (\text -> NewSearchText text)] []
, Html.text model.result
]
答案 0 :(得分:7)
是的,可以将查询字符串附加到响应中。首先,扩充您的消息类型以处理其他数据:
type Msg
= NewSearchText String
| ReceivedResponse String (Result Http.Error SearchResult)
然后,更改Http.send
来电,将查询文字附加到ReceivedResponse
消息:
Http.send (ReceivedResponse query) request
最后,在update
中,在结果Msg
上的模式匹配中抓取查询:
case msg of
ReceivedResponse query (Ok response) ->
...
ReceivedResponse query (Err err) ->
...
为什么这样做?
Http.send
函数的第一个参数可以是一个消耗Result Http.Error SearchResult
并将其变为Msg
的任意函数。在原始代码中,该函数只是ReceivedResponse
,即Msg构造函数。更新Msg类型以便ReceivedResponse
获取两个参数时,ReceivedResponse
构造函数变为一个curried双参数函数,而ReceivedResponse "some query here"
是一个 - 参数函数接收Result
并返回Msg
。
答案 1 :(得分:5)
以这种方式:
在模型中添加两个整数:
requestsSent : Int
- 提出的请求数量。lastReceived : Int
- 您已处理的最新请求。修改ReceivedResponse
以将Int作为第一个值:
| ReceivedResponse Int (Result Http.Error SearchResult)
现在,无论何时发出请求,都要在模型中将requestsSent
增加1,然后按&#34;标记&#34;部分应用ReceivedResponse
:
Http.send (ReceivedResponse model.requestsSent) request
在update
功能中,检查Int
中的ReceivedResponse
是否大于lastReceived
。如果是,请对其进行处理,并将lastReceived
的值设置为此响应的Int。如果不是,请丢弃它,因为您已经处理了较新的请求。