我正在尝试实现一个简单的状态度量转换器,以统计项目的数量(使用ClojureScript)
(defn stateful-counter []
(fn [xf]
(let [counter (atom 0)]
(fn
([] (xf))
([result]
(xf (xf result @counter)))
([result _]
(swap! counter inc)
result)))))
当在一个序列上运行它时,我得到以下输出
(into [] (stateful-counter) (range 5))
[5]
这正是我预期的。
当我在核心.async通道上运行它时,我得到了一个由5组成的无限序列
(go (println
(<! (let [c (async/chan 1 (stateful-counter))]
(async/onto-chan! c (range 5))
(async/into []
(async/take 10 c))))))
[5 5 5 5 5 5 5 5 5 5]
如果我不使用 `(async/take 10 _)`,似乎会陷入无限循环。期望的结果是 [5]。
我还尝试使用来自xforms库的`net.cgrand.xforms/count`并得到相同的不期望的结果
(go (println
(<! (let [c (async/chan 1 xforms/count)]
(async/onto-chan! c (range 5))
(async/into []
(async/take 10 c))))))
我假设我在`stateful-counter`中做了实现错误,导致了循环。但是,我很困惑,xforms/count产生了相同(不期望)的结果。
这是一个ClojureScript片段,但我已经能够使用Clojure生成相同的不期望结果。
有人能帮我理解为什么在核心.async通道上应用状态度量转换器会导致无限序列吗?
EDIT:在Clojure中看到了相同的不期望行为。