【发布时间】:2015-07-28 13:32:00
【问题描述】:
我正在使用 HTTP Kit 发出请求,我希望它们是异步的,但我也想缓存响应。我希望请求是异步的的原因是我正在同时发出几个请求并且我希望它们并行运行。
这是我的函数,它同时发出多个请求。
(defn parallel-requests-1 [urls]
(let [; Dispatch all requests to run concurrently.
responses (doall (map #(http/get %) urls))
; Realise all promises.
realised (doall (map deref responses))
; Extract response body.
bodies (map :body realised)]
bodies))
(parallel-requests-1 ["http://example.com", "http://example.net"])
这纯粹是为了说明目的,以证明我不想只是 deref 承诺并记住它。
现在我想使用memoize 添加缓存。我试过这个:
(def memoized-get (memoize http/get))
(defn parallel-requests-2 [urls]
(let [; Dispatch all requests to run concurrently.
responses (doall (map #(memoized-get %) urls))
; Realise all promises.
realised (doall (map deref responses))
; Extract response body.
bodies (map :body realised)]
bodies))
所有迹象都表明这很有效。
这是一个明智的解决方案吗?我担心缓存承诺可能会造成某种资源泄漏。
【问题讨论】:
-
记忆承诺比记忆值更明智,因为这样你就没有竞争条件,以防有人多次触发操作,因为记忆将在操作开始时发生而不是结束的时候。
-
此外,缓存的 promise 将包含比其结果更多的信息。如果被拒绝,它将让您了解拒绝的原因,这在某些情况下可能很有用。例如,如果远程服务不可用,您可以选择重试,但如果原因为空结果,则不重试。或者您可能只是想记录/显示原因(再次)。
-
Promise 确实已经记住了它们的结果——我不清楚你希望通过调用 memoize 来实现什么。
-
Promises memoize 自己的结果,但是对
http/get的调用每次返回不同的promise,因此会产生一个新的请求。我想缓存http/get的结果,即存储每个结果承诺。
标签: clojure promise core.async