(defonce instance
(atom
{:id nil
:canvas nil
:subscribers #{"test1" "test2"}))
(defn replace-canvas [canvas id]
(println "replaced" id "'s canvas"))
(defn update-subscribers
[k r old-state new-state]
(pprint "this function is being called")
(pprint "I can execute consecutive forms")
(map (partial replace-canvas (new-state :canvas))
(new-state :subscribers)))
(add-watch instance :update-subs update-subscribers)
当实例原子发生变化时,表面上调用了watch函数,因为“正在调用此函数”和“我可以执行连续表单”都被打印,但地图函数似乎永远不会发生。我不知道为什么会这样,而且我在add-watch的文档中找不到任何可以放在watch函数内部的限制。
即使我用更简单的东西替换更新订阅者中的地图,例如
(map println (new-state :subscribers))
地图似乎没有任何效果。
任何帮助将不胜感激, 谢谢!
答案 0 :(得分:4)
map
函数是惰性的,所以只有当调用者实现它产生的序列时它才会起作用(当一个函数被调用作为手表的一部分时,情况并非如此,因为结果基本上被抛弃了)
您要么想要将map
电话打包在doall
中,要么改为使用doseq
(这对于副作用代码更为惯用):
(doseq [subscriber (:subscribers new-state)]
(replace-canvas (:canvas new-state) subscriber))
另请注意,(:canvas new-state)
比(new-state :canvas)
- 首先是关键字更具惯用性。