首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止关闭!-ing在进入-chan之前

如何防止关闭!-ing在进入-chan之前
EN

Stack Overflow用户
提问于 2016-05-06 13:39:38
回答 2查看 214关注 0票数 0

我想运行这样的代码

代码语言:javascript
复制
(->> input
     (partition-all 5)
     (map a-side-effect)
     dorun)

异步分割输入输出(a-副作用)。

然后我编写了下面的实验代码。

代码语言:javascript
复制
;; using boot-clj
(set-env! :dependencies '[[org.clojure/core.async "0.2.374"]])
(require '[clojure.core.async :as async :refer [<! <!! >! >!!]])

(let [input (range 18)
      c (async/chan 1 (comp (partition-all 5)
                            (map prn)))]
  (async/onto-chan c input false)
  (async/close! c))

对此代码的解释:

  • 实际上,在运行之前,没有定义输入中的元素及其数量,而且输入中的元素可以从0到10被取为一些数字。
  • async/onto-chan用于将元素(输入的片段)放入通道c中,并将多次调用,因此第三个参数是false
  • prna-side-effect的替代品。

我希望上面的代码打印出来

代码语言:javascript
复制
[0 1 2 3 4]
[5 6 7 8 9]
[10 11 12 13 14]
[15 16 17]

然而,在REPL中,它没有打印字符。

然后我增加了等待的时间,就像这样

代码语言:javascript
复制
(let [c (async/chan 1 (comp (partition-all 5)
                            (map prn)))]
  (async/onto-chan c (range 18) false)
  (Thread/sleep 1000) ;wait
  (async/close! c))

这段代码给出了上面我的预期输出。

然后我检查core.async/onto-chan

我想发生了什么:

  1. c频道是在我的代码中编辑的。
  2. core.async/onto-chan的每一项论证(core.async/>!)由于通道c被关闭,在onto-chango-loop中都是徒劳的。

有明确的方法将项目放在close!之前吗?编写不使用onto-chan的同步版本的go-loop

还是我的想法错了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-07 08:28:56

您使用Thread.sleep的第二个示例只是错误地“工作”。

它起作用的原因是,从c的换能器中得到的每个转换结果值都是nil,而且由于通道中不允许nil,因此抛出了异常,而c没有值:这就是允许生产者onto-chan继续放入通道而不是等待的原因。如果将第二个示例粘贴到REPL中,您将看到四个堆栈跟踪--每个分区一个。

当然,nil是由于prn上的映射而产生的,这是一个对所有输入返回nil的副作用函数。

如果我正确理解你的设计,你的目标是这样做:

代码语言:javascript
复制
(defn go-run! [ch proc]
  (async/go-loop []
    (when-let [value (<! ch)]
      (proc value)
      (recur))))

(let [input (range 18)
      c (async/chan 1 (partition-all 5))]
  (async/onto-chan c input)
  (<!! (go-run! c prn)))
  • 你确实需要一个生产者和一个消费者,否则你的程序将被阻止。我介绍了一个go-loop消费者。
  • 通常情况下,map和副作用不能很好地结合在一起,所以我已经将副作用prn提取到了消费者中。
  • onto-chan不能被称为“多次”(至少在显示的代码中是这样),因此它不需要false参数。
票数 1
EN

Stack Overflow用户

发布于 2016-05-06 15:04:12

采纳了巨魔的想法:

代码语言:javascript
复制
(let [c (async/chan 1 (comp (partition-all 5)
                            (map prn)))
      put-ch (async/onto-chan c (range 18) false)]
  (async/alts!! [put-ch])
  (async/close! c))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37073900

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档