【问题标题】:How to create a channel from another with transducers?如何使用传感器从另一个通道创建通道?
【发布时间】:2015-09-25 23:31:00
【问题描述】:

我想从另一个只过滤特定消息的频道创建一个clojure.core.async 频道。因此,我找到了一个名为 filter<.> 的函数

=> (def c1 (chan))
=> (def c2 (filter< even? c1))
=> (put! c1 1)
=> (put! c1 2)
=> (<!! c2)
2

但是该函数及其朋友被标记为已弃用:

已弃用 - 此功能将被删除。改用换能器

有一些方法可以使用带有传感器的通道,例如带有xform 参数的chan。如何使用传感器从现有通道构建新通道?

【问题讨论】:

    标签: clojure core.async transducer


    【解决方案1】:

    我对此进行了一些研究,发现了一些有趣的文章(firstsecond),然后使用 pipeline 得到了一些工作

    (require '[clojure.core.async :as async :refer [chan <!! pipeline put!]])
    (def c1 (chan))
    (def c2 (chan))
    
    (pipeline 4 c2 (filter even?) c1)
    
    (put! c1 1)
    (put! c1 2)
    (<!! c2)
    ;;=> 2
    

    我链接的第二篇文章通过管道函数周围的一些辅助函数使这更清晰:

    (defn ncpus []
      (.availableProcessors (Runtime/getRuntime)))
    
    (defn parallelism []
      (+ (ncpus) 1))
    
    (defn add-transducer
      [in xf]
      (let [out (chan (buffer 16))]
        (pipeline (parallelism) out xf in)
        out))
    

    然后您可以简单地将频道与

    (def c1 (chan))
    (def c2 (add-transducer c1 (filter even?))
    

    要完成答案,您发现自己可以以类似的方式使用管道:

    (defn pipe-trans
      [ci xf]
      (let [co (chan 1 xf)]
        (pipe ci co)
        co))
    (def c1 (chan))
    (def c2 (pipe-trans c1 (filter even?)))
    

    【讨论】:

    • 受您的启发,我使用pipe 创建了一个工厂方法。 (defn from-chan [ci xf] (let [co (chan 1 xf)] (pipe ci co) co))
    • 很好,很高兴我能帮上忙。
    • 我已经添加了您的工厂方法的一个版本,以尝试完成答案,以防其他人搜索它。
    • 注意到这一点:dev.clojure.org/jira/browse/ASYNC-153 似乎 pipe-trans 可以简化为 (defn pipe-trans [ci xf] (pipe ci (chan 1 xf))) 但它没有记录
    猜你喜欢
    • 2016-06-28
    • 2018-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    相关资源
    最近更新 更多