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

如何记忆一个使用Core.Async和非阻塞通道读取的函数?

毛勇
2023-03-14

对于使用core.async<!的函数,我希望使用memoize。例如

(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

**备注:我需要一个与<!兼容的解决方案。有关<!!,请参阅以下问题:如何记忆使用core.async和阻塞通道读取的函数?**

共有1个答案

朱翔
2023-03-14

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

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

注意,我们将使用<!!,而不是<!,因为在所有情况下,我们都需要这个功能块,直到通道上有数据为止。<!仅在go块内部的窗体中使用时才显示此行为。

然后,您可以通过使用foo组合这个函数来构造您的memoized函数,如下所示:

(def foo-memo (memoize (comp wait-for foo)))
(go (println (foo-memo 3))
 类似资料:
  • 默认情况下,通道发送和接收数据是阻塞的。然而我们可以使用select的一个default的选项来实现无阻塞发送或接收数据,甚至可以将多个select的case选项和default选项结合起来使用。 package main import "fmt" func main() { messages := make(chan string) signals := make(chan bo

  • 问题内容: 我有这段代码可以在Linux中从Serial读取,但是我不知道在读取SerialPort时阻塞和非阻塞之间有什么区别,在哪种情况下哪个更好? 问题答案: 您提到的代码是IMO编码和注释不当的代码。该代码不符合POSIX的可移植性惯例,如正确设置终端模式和POSIX操作系统的串行编程指南中所述。该代码没有提到它使用非规范(也称为原始)模式,并且重用了“阻塞”和“非阻塞”术语来描述 VMI

  • 问题内容: Java中是否有非阻塞文件读取API?如果不是,在C ++中构建一个并通过JNI从Java应用程序中调用它是否明智? 问题答案: 不,不扩展。 可能是因为并非所有的操作系​​统都支持它。 Windows确实如此,从理论上讲,您可以编写Windows特定的C ++库,并通过JNI进行调用,但是将其与集成是很多工作。 我宁愿有一个工作线程将文件内容复制到管道中,并在管道的另一端进行非阻塞读

  • 问题内容: 我想使用打开管道,并对其具有非阻塞的“读取”访问权限。 我该如何实现? (我发现的示例都是阻塞/同步的) 问题答案: 设置如下: 现在您可以阅读: 完成后,清理:

  • 问题内容: 我需要使用逐行读取文件,但是没有像一次读取一个完整行的方法。有什么解决方案? 问题答案: NIO通常用于直接内存访问或块介导的批量数据传输。它可以做其他事情,但是其他功能与阻塞和非阻塞数据访问有更多关系。 因此,您可能想使用NIO来快速(或以非阻塞方式)获取数据。但是,如果要“逐行读取”,最好在NIO读取可用数据后进行行检测。可以通过在NIO刚刚读取的缓冲区上放置“行读取”外观来轻松实

  • 问题内容: 我正在尝试在Go中创建服务器和客户端,我已经设法与服务器和客户端进行通信。但是我的问题是,在golang中读取的TCP是非阻塞的。我想知道的是,golang中的读取是否有可能像C中的读取一样被阻塞。谢谢 编辑: 这是服务器的源代码: 和我的客户: 问题答案: 可以返回部分数据。从该文档,“如果某些数据是可用的,但不是LEN(P)个字节,读取常规返回什么是可用的,而不是等待更多。” 无论