clojure环中的重复评估

Lon*_*HDi 2 clojure ring

我正在学习 Clojure Ring。这是我的第一个处理程序:

(ns long-hdi.core
 (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"){:body "hello" :status 200})

(defn on-init[](println "Initializing..."))
(defn on-destroy[](println "destroying..."))
Run Code Online (Sandbox Code Playgroud)

这是 project.clj 配置文件:

   (defproject long-hdi "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :plugins [[lein-ring "0.9.7"]]
  :ring {:handler long-hdi.core/-main :init long-hdi.core/on-init :destroy long-hdi.core/on-destroy}
  :main ^:skip-aot long-hdi.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}})
Run Code Online (Sandbox Code Playgroud)

当我运行: lein ring server-headless 并浏览到http://localhost:3000 我看到它打印在控制台上“Hello, world!” 两次。为什么会打印2次?我想它只打印一次。然后我将源代码修改为:

...{:body args :status 200}...
Run Code Online (Sandbox Code Playgroud)

然后用谷歌浏览器浏览到http://localhost:3000 这一次,打印“Hello, world!” 在控制台上 3 次。为什么改为打印3次?

我正在使用 REPL-y 0.3.7、nREPL 0.2.12、Clojure 1.8.0、lein-ring "0.9.7"、Windows 10-64 位。

Jos*_*osh 5

问题不是因为您的代码而发生,但我将在下面向您展示如何修改您的代码以获得您想要的结果。

要在此处进行更多调查,请打开 Chrome 开发工具窗口(右键单击并选择“检查”)。转到顶部的网络选项卡。在左侧,您会在请求列表下看到一些有趣的内容: localhost以及favicon.ico. 因此,实际上,每次您重新加载浏览器时,它不仅会向页面发出请求,还会向页面图标发出请求,这就是为什么您会看到两个请求。Firefox(至少在我的情况下)只是在第一次加载后缓存图标,但 chrome 每次都从服务器请求它。

那么,你能做些什么呢?好吧,浏览器的每个请求都调用相同的处理程序。因此,您接下来需要探索路线。这允许您将特定浏览器请求映射到特定处理程序。因此,您可以简单地避免调用获取favicon. 作为让您入门的一个小工作示例,它可以让您看到请求在浏览器窗口中工作,而不是打印到命令行:

你的project.clj:

(defproject long-hdi "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure "1.8.0"]
                 [ring/ring-core "1.5.1"]
                 [ring/ring-jetty-adapter "1.5.1"]
                 [compojure "1.5.2"]]
  :main long-hdi.core)
Run Code Online (Sandbox Code Playgroud)

在您的主要源文件中:

(ns long-hdi.core
  (:require [ring.adapter.jetty]
            [compojure.core :refer :all]))

(def counter (atom 0))

(defn handler
  [req]
  (swap! counter inc)
  {:body (str "counter is: " @counter) :status 200})

(defroutes app
  (GET "/" [] handler))

(defn -main [& args]
  (ring.adapter.jetty/run-jetty app {:port 3000}))
Run Code Online (Sandbox Code Playgroud)

运行服务器,然后在浏览器窗口中打开它localhost:3000

$ lein run
Run Code Online (Sandbox Code Playgroud)

我希望这会有所帮助,并玩得开心!