下面是一个测试:
open System
open System.Threading
open Newtonsoft.Json
open Suave
open Suave.Logging
open Suave.Operators
open Suave.Filters
open Suave.Writers
let private configuration = {
defaultConfig with
bindings = [ HttpBinding.createSimple HTTP "0.0.0.0" 80 ]
}
let private getServerTime () : WebPart =
DateTime.UtcNow |> JsonConvert.SerializeObject |> Successful.OK >=> setMimeType "application/json"
let private webApplication =
choose
[
GET >=> choose
[
path "/servertime" >=> getServerTime ()
]
]
let start () =
let listening, server = startWebServerAsync configuration webApplication
server |> Async.Start
listening |> Async.RunSynchronously |> ignore
[<EntryPoint>]
let main _ =
start()
Thread.Sleep(Timeout.Infinite)
0在这个示例中,只调用一次getServerTime函数,这就是它,以后对端点的每一次调用都将返回原始结果。
我不明白为什么?当我使用带有参数的pathScan时,每次都会像预期的那样调用该函数,但在本例中,使用简单的get,只执行第一次调用,而这是定义为函数的。
但是我也完全不理解文档(从文档的流程、内容和整个文档结构.),所以答案可能很简单:)
发布于 2021-06-10 20:55:29
首先,我强烈建议你学习一元作文。这是理解这些事情的必要基础。它将让您了解什么是>=>和>>=,以及如何处理它们。
至于手头的问题:是的,您将getServerTime定义为一个函数,但这种类型并不重要,因为在构造webApplication值期间,只调用该函数一次。
服务器的结构是这样的,它实际上是一个函数HttpContext -> Async<HttpContext option>。它获取请求上下文并返回其修改后的版本。所有这些组合子-- choose和>=>等等--都与这样的函数一起工作。
表达式path "/servertime"也是这样的函数。从字面上看。你可以这样称呼它:
let httpCtx = ...
let newCtxAsync = path "/servertime" httpCtx而且,表达式getServerTime()也是这样的函数。所以你可以:
let httpCtx = ...
let newCtxAsync = getServerTime () httpCtx这就是WebPart类型。它是一个从上下文到新上下文的异步函数。
现在,>=>操作符所做的就是组合这些函数。使他们将上下文从一个next部件传输到另一个next部件。就这样。
在编写getServerTime函数时,您创建了一个始终返回相同内容的WebPart。就像这样:
let f x y = printf "x = %d" x
let g = f 42在这里,g是一个函数(就像一个WebPart是一个函数),但是每当它被调用时,它总是返回"x = 42"。为什么?因为我部分地应用了这个参数,所以它现在在g的定义中被“烤熟了”。与您在WebPart中创建的getServerTime中“烘焙”当前时间的方式一样。
如果希望每次返回不同的时间,则每次都需要重新创建WebPart。在每个调用上构建一个新的WebPart,其中一个调用的时间很长。这样做的最小改变可能是:
let private getServerTime () : WebPart =
let time : WebPart = fun ctx -> (DateTime.UtcNow |> string |> Successful.OK) ctx
time >=> setMimeType "text/plain"从表面上看,time的定义看起来很愚蠢:毕竟,let f x = g x总是可以被let f = g取代的,对吗?嗯,不总是这样。只要g是纯的。但是这里的网页部分不是:它取决于当前的时间。
这样,每当time way部件“运行”(这意味着它获得一个上下文作为参数)时,它将运行DateTime.UtcNow,然后将其传递给Successful.OK,然后将上下文传递给结果函数。
https://stackoverflow.com/questions/67927914
复制相似问题