当前位置: 首页 > 知识库问答 >
问题:

如何用尽一个通道的值,然后返回结果(ClojureScript)?

归鸿朗
2023-03-14

假设通道chan在队列上具有值“1”和“2”。

目标:创建一个函数,它接受chan并返回向量[1 2]。请注意,如果这个函数在返回它的值之前必须阻塞一段时间,我是完全没有问题的。

(defn chan->vector
  [chan]  
  (let [a (atom true) v []]
    (while (not-nil? @a)
      (go
        (reset! a (<! chan))
        (into v @a)
        (reset! a (<! chan))
      )
    ) v
  )
)

共有1个答案

卜弘文
2023-03-14

您应该使用core.async中的alts!来完成此任务(https://clojure.github.io/core.async/#clojure.core.async/alts!):

(def x (chan 10))

(go (>! x 1)
    (>! x 2)
    (>! x 3))

(defn read-all [from-chan]
  (<!! (go-loop [res []]
           (let [[v _] (alts! [from-chan] :default :complete)]
             (if (= v :complete)
               res
               (recur (conj res v)))))))

(read-all x) 
;; output: [1 2 3]

(read-all x)
;; output: []

(go (>! x 10)
    (>! x 20)
    (>! x 30)
    (>! x 40))

(read-all x)
;; output: [10 20 30 40]

go-loop内部,这个(A/alts![from-chan]:default:complete)尝试从通道读取任何值,如果没有可用的值,它会发出默认值,因此您将看到应该中断循环并返回累加值。

更新:由于CLJ中没有阻塞读取(<!!),您可以用以下方法重写它:

(defn read-all [from-chan]
  (go-loop [res []]
    (let [[v _] (alts! [from-chan] :default :complete)]
      (if (= v :complete)
        res
        (recur (conj res v)))))))

所以它会返回通道,然后从那里读取一个值:

(go (let [res (<! (read-all x))]
      (println res)
      ;; do something else
      ))
 类似资料:
  • 嗨我刚开始学习反应式编程 我这里有这段代码,我的过程应该是我将调用TokenRepository来获取令牌,然后使用token.getAccessToken()作为cardRepository.findAllCards()上的参数 想知道这是否可行吗?

  • 问题内容: 有点像这样: 但是,由于脚本是异步的,因此它将返回“”。那显然不是我想要的。 所以我尝试了这个: 我希望它能奏效,但是没有。为什么不?有人可以提出解决方案吗? 问题答案: 您应该对函数使用回调传递,并让它处理您的数据。

  • 问题内容: 我在此链接中看到了一些代码,并感到困惑:http : //www.darkcoding.net/software/go-lang-after-four- months/ 第二个值(确定)是什么意思? 问题答案: 接收操作符返回的布尔变量指示接收的值是在通道上发送的(true)还是由于通道关闭且为空而返回的零值(false)。 当Go程序的其他部分关闭或通道时,循环终止。在这种情况下,其

  • 问题内容: 我有这种简单的查询,它返回给定id的非空整数字段: 问题是,如果找不到ID,则结果集为空。我需要查询始终返回一个值,即使没有结果也是如此。 我有这个东西工作,但我不喜欢它,因为它运行相同子查询的2倍: 如果该行存在,则返回field1,否则返回0。有什么改进的方法吗? 谢谢! 编辑以下一些评论和答案 :是的,它必须在 单个查询语句中, 并且我不能使用count技巧,因为 我只需要返回1

  • 问题内容: 我在Go中有一个返回两个值的函数。我想将其作为goroutine运行,但是我无法弄清楚创建接收两个值的通道的语法。有人能指出我正确的方向吗? 问题答案: 使用两个值的字段定义自定义类型,然后创建该类型的。 编辑:我还添加了一个使用多个通道而不是自定义类型的示例(在底部)。我不确定哪个更惯用。 例如: 然后 使用自定义类型的频道(Playground)的示例: 产生: LOREM,5 I

  • 当集合中的文档存在或不存在时,我想返回True或False。但它总是返回错误。 我还在学习,谢谢你的帮助。