我正在尝试实现一个简单的状态转换器,用于计算元素数量(使用 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]
这正是我所期望的。
当我在核心异步通道上运行它时,我得到了一系列无穷的 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]。
我还尝试过使用 net.cgrand.xforms/count 从 xforms 库,但得到了相同的不期望的结果
(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 产生相同的不期望结果。
有人能帮助我理解为什么在核心异步通道上应用状态转换器导致无限序列吗?
编辑:同样不期望的行为在 Clojure 中看到了。