关于clojure:为什么我只能拿一包! 从这个频道?

Why am I only getting one take! from this channel?

试图了解渠道如何运作; 我不明白为什么我的take!在此REPL序列中只能运行一次,即使我尝试了多次推子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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>

是否是因为当通道上什么都没有时,我随后连续几次从通道中取出,从而留下了"空洞",这些空洞被后续的看跌期权所填充,直到通道以某种方式恢复到甚至是看跌期权的数量为止?


在这种异步情况下,println行为很奇怪。
如果您最后一次调用是"接管!" fn然后,您将最终获得打印结果,但最后四个调用是" put!"。 fn然后您必须在nrepl-server终端上找到打印结果。

这种行为和必要的工作空间是在core.async的Timothy Baldridge视频的开头介绍的

这是我在emacs中的两帧的一个屏幕截图,一个用于nrepl,另一个用于nrepl-server输出


不要用go包装put!take!。 想要!>进入内部:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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