(def file (agent nil))
(defn read-file []
(if (= @file nil)
(do
(println "read-file")
(send-off file #(slurp %2) (io/resource "file.txt")))
nil)
@file)
如果我第一次调用read-file
,则返回nil。对于所有后续调用,它将返回文件内容。这是为什么?当我使用atom
时,它可以正常工作。同样为什么#(slurp %2)
需要第二个参数?当我只给%
时它不起作用?我收到以下错误:
clojure.lang.ArityException: Wrong number of args (2) passed to: core/read-file/fn--3603
答案 0 :(得分:2)
代理上的Deref提供当前状态的快照。代理程序使用nil
进行初始化,因此在初始状态下取消引用它会返回nil
。
如果您想等到结果可用,您可以在代理上使用future
或致电await
。如果只有一个动作产生结果,future
将是我的第一选择。在这个特定的例子中,我只是编写(slurp (io/resource "file.txt"))
而没有任何并发构造。
答案 1 :(得分:2)
代理是错误的并发原语。它具有您不想要的所有特征,而且没有您想要的特性。相反,由于您要缓存的内容是一项昂贵的操作,请使用延迟:
(let [file (delay (slurp (io/resource "file.txt")))]
(defn read-file []
@file))