gpt4 book ai didi

node.js - 如何耗尽 channel 的值然后返回结果(ClojureScript)?

转载 作者:搜寻专家 更新时间:2023-10-31 23:31:30 25 4
gpt4 key购买 nike

假设 channel 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
)
)

结果: 我的 REPL 卡住并最终吐出一个巨大的错误。我开始意识到这是因为 (go ...) block 是异步的,所以会立即返回。因此,我的 (while ...) 循环中的原子永远不会有机会被设置为 nil 并且循环永远不会终止。

那么如何才能达到预期的效果呢?如果相关,我正在使用 ClojureScript 并以 nodejs 为目标。

最佳答案

你应该使用alts!来自 core.async完成这个任务( 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)尝试从 channel 读取任何值,如果立即没有可用值,它会发出默认值,因此您会看到您应该打破循环并返回累积值。

更新:由于cljs中没有blocking read ( <!! ),你可以重写如下:

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

所以它将返回 channel ,然后只从那里读取一个值:

(go (let [res (<! (read-all x))]
(println res)
;; do something else
))

关于node.js - 如何耗尽 channel 的值然后返回结果(ClojureScript)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34560423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com