为什么我只能拿一个!来自这个频道?

时间:2014-05-23 07:27:22

标签: clojure

试图了解渠道的运作方式;我不知道为什么我的take!只能在这个REPL序列中工作一次,即使我尝试了多次放置:

cplay.core> (def h (chan))
#'cplay.core/h
cplay.core> (go (put! h "hello"))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@4afdd6ba>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@9fe39a1>
cplay.core> hello

cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@206564e9>
cplay.core> (go (put! h "hello"))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@6c0ec468>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@60c85184>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@3edc08c3>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@6a7b295f>
cplay.core> (go (put! h "hello"))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@60331d8b>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@557c3bce>
cplay.core> (go (put! h "hello"))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@203fdcfb>
cplay.core> (go (put! h "hello"))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@ed11c1>
cplay.core> (go (take! h (fn [x] (println x))))
#<ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@6c7ea146>
cplay.core> 

是不是因为当频道上没有任何内容时,我会连续几次从频道中取出,从而留下&#34;空洞&#34;由后续看跌期权填补,直到通道以某种方式返回甚至数量的看跌期权?

2 个答案:

答案 0 :(得分:1)

在这个异步场景中,println行为很安静。 如果你最后一次调用是“拿!”那么你最终会在你的repl中得到打印结果,但最后四次调用就是“put!” fn然后你必须在nrepl-server终端上找到打印结果。

此行为和必要的工作区在core.async的Timothy Baldridge video开头引入

这里我在emacs中的2帧one screenshot,一个用于nrepl,另一个用于nrepl-server输出

答案 1 :(得分:0)

不要将put!take!go一起包裹。在里面你想要<!!>

user=> (require '[clojure.core.async :refer (chan put! take! <! >!)])
nil
user=> (def h (chan))
#'user/h
user=> (put! h "hello")
true
user=> (take! h println)
hello
nil
user=> (put! h "hello")
true
user=> (take! h println)
hello
nil
user=> (put! h "hello")
true
user=> (take! h println)
hello
nil
user=> (put! h "hello")
true
user=> (take! h println)
hello
nil
user=> (take! h println)
nil
user=> (put! h "hello")
hello
true