如何用RemoteData处理非JSON数据并配置自定义解码器?
解决方法:用RemoteData整合自定义字符串解码逻辑
你需要把HTTP请求的字符串响应、自定义解码逻辑,和RemoteData的状态管理结合起来,核心思路是先把请求结果和解码绑定,再把嵌套的错误状态转换成你需要的RemoteData String (List Foo)格式。下面是具体步骤:
1. 绑定请求与自定义解码
先用Http.map把Http.getString的字符串响应和你的Foo.decode解码器结合,生成一个返回Result的请求——这样能区分「HTTP请求失败」和「请求成功但解码失败」两种错误:
getFoosRequest : String -> Http.Request (Result String (List Foo)) getFoosRequest url = Http.getString url |> Http.map Foo.decode
2. 转换RemoteData状态
RemoteData.sendRequest会返回Cmd (WebData (Result String (List Foo)))(WebData a等价于RemoteData Http.Error a),我们需要把这个嵌套状态转换成你需要的RemoteData String (List Foo):
convertWebData : RemoteData Http.Error (Result String (List Foo)) -> RemoteData String (List Foo) convertWebData webData = case webData of RemoteData.NotAsked -> RemoteData.NotAsked RemoteData.Loading -> RemoteData.Loading RemoteData.Failure httpErr -> -- 将HTTP错误转为字符串作为错误信息 RemoteData.Failure (Http.errorToString httpErr) RemoteData.Success (Err decodeErr) -> -- 解码失败时,把解码错误作为错误信息 RemoteData.Failure decodeErr RemoteData.Success (Ok foos) -> -- 解码成功,返回最终的Foo列表 RemoteData.Success foos
3. 整合到消息系统
假设你的消息类型定义如下:
type Msg = ReceiveFoos (RemoteData String (List Foo)) | HandleRawResponse (RemoteData Http.Error (Result String (List Foo)))
发送请求的函数可以写成:
fetchFoos : String -> Cmd Msg fetchFoos url = getFoosRequest url |> RemoteData.sendRequest |> Cmd.map HandleRawResponse
最后在update里处理原始响应,转换成你需要的ReceiveFoos消息:
update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of HandleRawResponse rawData -> let processedData = convertWebData rawData in -- 这里可以直接更新model,或者触发ReceiveFoos消息 ( { model | foos = processedData }, Cmd.none ) ReceiveFoos foosData -> -- 处理最终结果,更新状态等 ( { model | foos = foosData }, Cmd.none )
关于自定义字符串处理的通用说明
当然可以自定义任何字符串处理逻辑!Http.getString拿到响应体后,你可以用Http.map做任意转换:解析CSV、XML、自定义文本格式,甚至做字符串校验、预处理等等——只要你有对应的处理函数(通常用Result err a包装成功/失败结果),再按照上面的方式整合到RemoteData的状态管理里就可以了。RemoteData只是帮你管理请求的生命周期状态,响应体的处理完全由你掌控,灵活性很高。
内容的提问来源于stack exchange,提问作者zoul
相关产品推荐
相关产品推荐

