如何访问寓言的承诺结果
How to access Fable's promise results
刚开始使用寓言/Elmish/F#,但在完成基本概念时卡住了...
代码的目标是执行一个简单的 HTTP GET 请求,然后 post 在网页上向用户发送 GET 请求的结果。
想法是使用 Fable Promise
或 async
执行 GET 请求并 return 结果,然后可以使用 Elmish 和 Fable 将结果显示在网页上。
我预计网页(localhost)会输出一个包含GET请求响应的文本字符串,但我在网页上只得到了“[object Promise]”。但是,GET 请求的所需响应会记录在浏览器控制台上。如果我在承诺正文中发出带有 txt
的 printfn 命令(在 return
之前),我还可以在浏览器控制台中看到 GET 请求的结果。
因此:我不知道如何访问承诺的结果。请帮忙,我错过了什么?
来自 [Fable][1] 的示例应用程序,创建了一个图像 "container" 并根据 HTTP 获取的结果放置了一个图像,但我需要使用文本(json 字符串)。
这是我的代码:
module App
open Elmish
open Fable.React
open Elmish.React
open Fable.React.Props
open Fable.Import
open Fable.PowerPack
open Fetch
// CallAPI
let getMe = promise {
let! res = fetch "https://reqres.in/api/users/2" []
let! txt = res.text()
// Access your resource here
Browser.console.log txt
return txt
}
//State
type MyInputString =
{Response : string}
// Message
type Message =
|ShowResponse
|Error
let getFromAPI =
getMe |> sprintf "%A"
//Update
let update msg model =
match msg with
|ShowResponse -> {Response = getFromAPI }
|Error -> {Response = "Errrrrr"}
//Helper function
let text(content:string) : ReactElement = unbox content
//Helper function
let init() = {Response = ""}
//View
let view model dispatch =
div
[]
[
div [] [ input[ Type "text"] ]
button [ OnClick (fun _ -> dispatch ShowResponse ) ] [ text "Show Me"]
div [] []
div [] [text (model.Response)]
]
Program.mkSimple init update view
|> Program.withReactSynchronous "werk"
|> Program.withConsoleTrace
|> Program.run ```
[1]: https://fable.io
如果您按照精灵模式进行操作,则可以执行以下操作。这可能会产生一些错误,但应该足以让您继续:
使用 mkProgram,因为它可以让您灵活地指定 Cmd 回调
Program.mkProgram init update view
|> Program.withReact "elmish-app"
|> Program.withConsoleTrace
|> Program.run
确保您区分模型和消息
type Model = {
UserMessage: string
ErrorMessage: string
}
添加消息类型以接收承诺结果并处理错误:
type Message =
| Loading
| ShowResponse of Result<string,string>
| Error of exn
你的 init 应该 return model 和 Cmd 现在因为签名已经改变(见下面的更新):
let init() = { UserMessage= "" ; ErrorMessage= "" } , Cmd.ofMsg Loading
更改您的更新功能,签名现在已更改,因为我们正在使用 mkProgram。请注意,当您调用 Cmd.ofPromise 时,您将 ShowResponse 和 Error 消息作为回调传递 -ShowResponse on success 和 Error if any bad happens in your promise code.
//update signature has changed from
msg -> model -> model
//to:
msg -> model -> (model*Cmd<msg>)
let update msg model =
match msg with
| Loading ->
{ model with UserMessage= "Loading" },
Cmd.ofPromise (getMe ) () ShowResponse Error
| ShowResponse resp ->
match resp with
| Ok str ->
{ model with UserMessage = str }, Cmd.none
| Error str ->
{ model with ErrorMessage = str }, Cmd.none
| Error exn -> { model with ErrorMessage = string exn }, Cmd.none
Promises 是一种基本的命令式结构——您只能使用副作用从中获取价值。它们不像 C# 中的任务,它也可以同步产生一个值。这意味着您的模型必须有两种与 getMe 相关的状态:等待 getMe 完成时的状态,以及 getMe 完成时的状态。每个状态都会有自己的消息和自己的更新案例。第一种情况的处理程序将使用 Cmd.ofSub 开始 getMe,并确保当承诺完成时,它具有发送第二条消息的副作用,这将在 UI 中显示承诺的结果].
所以除了ShowResponse和Error之外,还需要第三个消息MakeRequest。下面的代码只是一个草图(未经测试)但说明了这一点:
// Message
type Message =
| MakeRequest
| ShowResponse of string
| Error
let getMe dispatch =
promise {
let! res = fetch "https://reqres.in/api/users/2" []
let! txt = res.text()
// Access your resource here
Browser.console.log txt
dispatch (ShowResponse txt)
}
//Update
let update msg model =
match msg with
| MakeRequest -> { model with Response = "Wait..." },
Cmd.ofSub(fun dispatch -> getMe dispatch |> Promise.start)
| ShowResponse msg -> { model with Response = msg }, Cmd.empty
| Error -> { model with Response = "Errrrrr"}, Cmd.empty
刚开始使用寓言/Elmish/F#,但在完成基本概念时卡住了...
代码的目标是执行一个简单的 HTTP GET 请求,然后 post 在网页上向用户发送 GET 请求的结果。
想法是使用 Fable Promise
或 async
执行 GET 请求并 return 结果,然后可以使用 Elmish 和 Fable 将结果显示在网页上。
我预计网页(localhost)会输出一个包含GET请求响应的文本字符串,但我在网页上只得到了“[object Promise]”。但是,GET 请求的所需响应会记录在浏览器控制台上。如果我在承诺正文中发出带有 txt
的 printfn 命令(在 return
之前),我还可以在浏览器控制台中看到 GET 请求的结果。
因此:我不知道如何访问承诺的结果。请帮忙,我错过了什么? 来自 [Fable][1] 的示例应用程序,创建了一个图像 "container" 并根据 HTTP 获取的结果放置了一个图像,但我需要使用文本(json 字符串)。
这是我的代码:
module App
open Elmish
open Fable.React
open Elmish.React
open Fable.React.Props
open Fable.Import
open Fable.PowerPack
open Fetch
// CallAPI
let getMe = promise {
let! res = fetch "https://reqres.in/api/users/2" []
let! txt = res.text()
// Access your resource here
Browser.console.log txt
return txt
}
//State
type MyInputString =
{Response : string}
// Message
type Message =
|ShowResponse
|Error
let getFromAPI =
getMe |> sprintf "%A"
//Update
let update msg model =
match msg with
|ShowResponse -> {Response = getFromAPI }
|Error -> {Response = "Errrrrr"}
//Helper function
let text(content:string) : ReactElement = unbox content
//Helper function
let init() = {Response = ""}
//View
let view model dispatch =
div
[]
[
div [] [ input[ Type "text"] ]
button [ OnClick (fun _ -> dispatch ShowResponse ) ] [ text "Show Me"]
div [] []
div [] [text (model.Response)]
]
Program.mkSimple init update view
|> Program.withReactSynchronous "werk"
|> Program.withConsoleTrace
|> Program.run ```
[1]: https://fable.io
如果您按照精灵模式进行操作,则可以执行以下操作。这可能会产生一些错误,但应该足以让您继续:
使用 mkProgram,因为它可以让您灵活地指定 Cmd 回调
Program.mkProgram init update view
|> Program.withReact "elmish-app"
|> Program.withConsoleTrace
|> Program.run
确保您区分模型和消息
type Model = {
UserMessage: string
ErrorMessage: string
}
添加消息类型以接收承诺结果并处理错误:
type Message =
| Loading
| ShowResponse of Result<string,string>
| Error of exn
你的 init 应该 return model 和 Cmd 现在因为签名已经改变(见下面的更新):
let init() = { UserMessage= "" ; ErrorMessage= "" } , Cmd.ofMsg Loading
更改您的更新功能,签名现在已更改,因为我们正在使用 mkProgram。请注意,当您调用 Cmd.ofPromise 时,您将 ShowResponse 和 Error 消息作为回调传递 -ShowResponse on success 和 Error if any bad happens in your promise code.
//update signature has changed from
msg -> model -> model
//to:
msg -> model -> (model*Cmd<msg>)
let update msg model =
match msg with
| Loading ->
{ model with UserMessage= "Loading" },
Cmd.ofPromise (getMe ) () ShowResponse Error
| ShowResponse resp ->
match resp with
| Ok str ->
{ model with UserMessage = str }, Cmd.none
| Error str ->
{ model with ErrorMessage = str }, Cmd.none
| Error exn -> { model with ErrorMessage = string exn }, Cmd.none
Promises 是一种基本的命令式结构——您只能使用副作用从中获取价值。它们不像 C# 中的任务,它也可以同步产生一个值。这意味着您的模型必须有两种与 getMe 相关的状态:等待 getMe 完成时的状态,以及 getMe 完成时的状态。每个状态都会有自己的消息和自己的更新案例。第一种情况的处理程序将使用 Cmd.ofSub 开始 getMe,并确保当承诺完成时,它具有发送第二条消息的副作用,这将在 UI 中显示承诺的结果].
所以除了ShowResponse和Error之外,还需要第三个消息MakeRequest。下面的代码只是一个草图(未经测试)但说明了这一点:
// Message
type Message =
| MakeRequest
| ShowResponse of string
| Error
let getMe dispatch =
promise {
let! res = fetch "https://reqres.in/api/users/2" []
let! txt = res.text()
// Access your resource here
Browser.console.log txt
dispatch (ShowResponse txt)
}
//Update
let update msg model =
match msg with
| MakeRequest -> { model with Response = "Wait..." },
Cmd.ofSub(fun dispatch -> getMe dispatch |> Promise.start)
| ShowResponse msg -> { model with Response = msg }, Cmd.empty
| Error -> { model with Response = "Errrrrr"}, Cmd.empty