Clojure 记住承诺是否明智?
我使用HTTP工具包发出请求,我希望它们是异步的,但我也希望缓存响应。我之所以希望请求是异步的,是因为我同时发出几个请求,并且希望它们并行运行Clojure 记住承诺是否明智?,clojure,promise,core.async,Clojure,Promise,Core.async,我使用HTTP工具包发出请求,我希望它们是异步的,但我也希望缓存响应。我之所以希望请求是异步的,是因为我同时发出几个请求,并且希望它们并行运行 (defn parallel-requests-1 [urls] (let [; Dispatch all requests to run concurrently. responses (doall (map #(http/get %) urls)) ; Realise all promises. r
(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"])
下面是我的函数,它并行地发出多个请求
(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"])
这纯粹是为了说明,以证明我不想只是derefpromise并记住它
现在我想使用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))
所有迹象表明,这是一个很好的工作
这是一个合理的解决方案吗?我担心的是缓存承诺可能会造成某种资源泄漏。是的,记住承诺是明智的。事实上,在这种情况下,这可能是最明智的解决方案。毕竟,
http/get
返回的就是这个函数,这就是您想要记忆的函数
就资源泄漏而言,无论你是履行承诺还是履行承诺的价值,这都不应该是一个比平常更大的问题。承诺基本上只是一种状态,一旦它
交付,它就会引用价值代码>ed。因此,对于此引用,您有一点开销,但与整个响应相比,它是微不足道的。记住承诺比记住价值更明智,因为这样你就不会有竞争条件,以防有人多次触发操作,因为记住将在操作开始时发生,而不是在操作结束时发生。此外,缓存的承诺将包含比其结果更多的信息。如果被拒绝,它将允许您访问拒绝的原因,这在某些情况下可能很有用。例如,如果远程服务不可用,您可以选择重试,但如果原因是空结果,您可以选择不重试。或者,您可能只想记录/显示原因(再次)。承诺确实已经将其结果记录下来了——我不清楚您希望通过调用memoize实现什么。承诺记录自己的结果,但调用http/get
每次都返回不同的承诺,从而产生新的请求。我想缓存http/get
的结果,即存储每个结果承诺。相关:非常感谢。在过去,我有一个有限的chan
s(当我试图创建太多线程时,线程刚刚阻塞),所以我想确定一下。到目前为止,我在缓存承诺方面没有遇到任何问题(尽管这仅仅是一天)。