首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不理解Suave API,总是返回相同的结果

不理解Suave API,总是返回相同的结果
EN

Stack Overflow用户
提问于 2021-06-10 20:12:35
回答 1查看 71关注 0票数 0

下面是一个测试:

代码语言:javascript
复制
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,只执行第一次调用,而这是定义为函数的。

但是我也完全不理解文档(从文档的流程、内容和整个文档结构.),所以答案可能很简单:)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-10 20:55:29

首先,我强烈建议你学习一元作文。这是理解这些事情的必要基础。它将让您了解什么是>=>>>=,以及如何处理它们。

至于手头的问题:是的,您将getServerTime定义为一个函数,但这种类型并不重要,因为在构造webApplication值期间,只调用该函数一次。

服务器的结构是这样的,它实际上是一个函数HttpContext -> Async<HttpContext option>。它获取请求上下文并返回其修改后的版本。所有这些组合子-- choose>=>等等--都与这样的函数一起工作。

表达式path "/servertime"也是这样的函数。从字面上看。你可以这样称呼它:

代码语言:javascript
复制
let httpCtx = ...
let newCtxAsync = path "/servertime" httpCtx

而且,表达式getServerTime()也是这样的函数。所以你可以:

代码语言:javascript
复制
let httpCtx = ...
let newCtxAsync = getServerTime () httpCtx

这就是WebPart类型。它是一个从上下文到新上下文的异步函数。

现在,>=>操作符所做的就是组合这些函数。使他们将上下文从一个next部件传输到另一个next部件。就这样。

在编写getServerTime函数时,您创建了一个始终返回相同内容的WebPart。就像这样:

代码语言:javascript
复制
let f x y = printf "x = %d" x
let g = f 42

在这里,g是一个函数(就像一个WebPart是一个函数),但是每当它被调用时,它总是返回"x = 42"。为什么?因为我部分地应用了这个参数,所以它现在在g的定义中被“烤熟了”。与您在WebPart中创建的getServerTime中“烘焙”当前时间的方式一样。

如果希望每次返回不同的时间,则每次都需要重新创建WebPart。在每个调用上构建一个新的WebPart,其中一个调用的时间很长。这样做的最小改变可能是:

代码语言:javascript
复制
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,然后将上下文传递给结果函数。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67927914

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档