使用 Klipse 和 Reagent 的 clojurescript 中的时间间隔非常(太)快

Time interval in clojurescript using Klipse and Reagent going very (too) fast

您好,我正在尝试 ClojureScript,并且我几乎使用 Klipse 作为我的 REPL。这可能不是它的预期用途,但因为我没有做任何太复杂的事情,所以现在没问题。

我遇到的一个问题是尝试设置计时器。我的代码是:

(ns my.reagent-examples
  (:require [reagent.core :as r]))

(when-let [element (js/document.getElementById "app")]
  (r/render-component [component] element))

;; State
(def app-state (r/atom 0)) ;; Initial value is 0

;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms

;; "Seconds elapsed" component 
(defn timer []
  [:div (str "Seconds elapsed: " @app-state)])

它显示了一个计时器,但它太快了,而且似乎随着时间的流逝而加速。预期结果是计数器每秒递增。

我完整的 Klipse 文件是这样的:

<!DOCTYPE html>

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css">
  <script>
    window.klipse_settings = {
      selector: '.language-klipse', // css selector for the html elements you want to klipsify
      selector_reagent: '.language-reagent', // selector for reagent snippets
    };
  </script>
</head>

<body>

  <pre><code class="language-reagent">
(ns my.reagent-examples
  (:require [reagent.core :as r]))
(when-let [element (js/document.getElementById "app")]
  (r/render-component [component] element))
;; State
(def app-state (r/atom 0)) ;; Initial value is 0
;; Increment seconds
(js/setInterval #(swap! app-state inc) 1000) ;; Increment app-state every 1000ms
;; "Seconds elapsed" component 
(defn timer []
  [:div (str "Seconds elapsed: " @app-state)])
</code></pre>

  <script src="https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js"></script>
</body>

(运行 整页中的代码段以查看计时器)

编辑:我看起来像个傻瓜,因为在代码片段中,计时器通常看起来像 运行,但是当我用 Google [=34] 打开完全相同的 HTML 文件时=] 或 Firefox,计时器出错了。这可能是什么原因?

EDIT2:似乎如果您更改代码段上的内容,您会看到计时器走得更快,是因为它渲染的时间太多了吗?

问题可能是当您编辑和保存代码时,它会 hot-reloaded 在您的浏览器中并启动另一个 js/setInterval 而不会停止前一个代码。

您可以通过在 defonce 定义中调用 js/setInterval 来修复它,该定义将在第一次加载时仅执行一次,并且不会在重新加载时调用:

(defonce timer-increment-interval
  (js/setInterval #(swap! app-state inc) 1000)) ;; Increment app-state every 1000ms