gpt4 book ai didi

clojure - 如何内存一个使用 core.async 和非阻塞 channel 读取的函数?

转载 作者:行者123 更新时间:2023-12-01 05:11:19 24 4
gpt4 key购买 nike

我想使用 memoize对于使用 core.async 的函数和 <!例如

(defn foo [x]
(go
(<! (timeout 2000))
(* 2 x)))

(在现实生活中,为了缓存服务器调用的结果可能很有用)

我能够通过编写 memoize 的 core.async 版本来实现这一点(几乎与 memoize 相同的代码):
(defn memoize-async [f]
(let [mem (atom {})]
(fn [& args]
(go
(if-let [e (find @mem args)]
(val e)
(let [ret (<! (apply f args))]; this line differs from memoize [ret (apply f args)]
(swap! mem assoc args ret)
ret))))))

使用示例:
(def foo-memo (memoize-async foo))
(go (println (<! (foo-memo 3)))); delay because of (<! (timeout 2000))

(go (println (<! (foo-memo 3)))); subsequent calls are memoized => no delay

我想知道是否有更简单的方法可以达到相同的结果。

**备注:我需要一个适用于 <! 的解决方案.对于 <!! ,看到这个问题: How to memoize a function that uses core.async and blocking channel read? **

最佳答案

您可以为此使用内置的 memoize 功能。首先定义一个从 channel 读取并返回值的方法:

 (defn wait-for [ch]
(<!! ch))

请注意,我们将使用 <!!而不是 <!因为我们想要这个功能 block ,直到在所有情况下 channel 上都有数据。 <!只有在 go block 内的表单中使用时才会表现出这种行为。

然后,您可以通过将此函数与 foo 组合来构造您的内存函数。 ,像这样:
(def foo-memo (memoize (comp wait-for foo)))
foo返回一个 channel ,所以 wait-for将阻塞直到该 channel 有一个值(即,直到 foo 内的操作完成)。
foo-memo可以像上面的例子一样使用,除了你不需要调用 <!因为 wait-for将为您阻止:
(go (println (foo-memo 3))

你也可以在 go block 之外调用它,它会像你期望的那样运行(即阻塞调用线程直到 foo 返回)。

关于clojure - 如何内存一个使用 core.async 和非阻塞 channel 读取的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24698536/

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