异步 – 如何使用Om Figwheel core.async写入可重新加载的异步代码?

我想写一个像时钟应用程序的东西.状态基本上是一个重复递增的数字.这里可以看到一种做法.

(ns chest-example.core
  (:require [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true]
            [cljs.core.async :as async])
  (:require-macros [cljs.core.async.macros :refer [go]]))

(defonce app-state (atom {:time 0}))

(defn clock-view [data owner]
  (reify
    om/IRender
    (render [_]
      (dom/div nil (pr-str data)))))

(go (while true
  (async/<! (async/timeout 1000))
  (om/transact! (om/root-cursor app-state) :time inc)))

(defn main []
  (om/root
    clock-view
    app-state
    { :target (. js/document (getElementById "clock"))}))

我遇到的问题是这不是可重新加载的代码.一旦我通过无花果轮刷新代码,增量变得更快,因为有几件事情更新状态.

我试图尝试各种想法(基本上使用不同的组件来拥有go语句代码)但我无法想出一些可行的东西.

有没有人对此有一个简洁的解决方案,或者我只是必须坚持在开发过程中?

最佳答案 你必须告诉goroutine何时停止运行.最简单的方法是发送关闭!告诉goroutine:

(ns myproject.core
  ;; imports
  )

(def my-goroutine
  (go-loop []
    (when (async/<! (async/timeout 1000))
      (om/transact! (om/root-cursor app-state) :time inc)
      (recur)))))

;; put in your on-reload function for figwheel
(defn on-reload []
  (async/close! my-goroutine))

任何在循环中运行的goroutine都需要发出信号以在重新加载时停止(通过figwheel:on-jsload config).

;; project.clj
(defproject ;; ...
  :figwheel {:on-jsload "myproject.core/on-reload"}
)

最好将长期运行的goroutine视为需要管理的资源.在golang中,将长期运行的goroutine视为流程/墓碑以确保正确拆卸是一种常见模式.同样应该应用于core.async的goroutines.

点赞