Joe*_*Joe 4 concurrency clojure promise core.async
我有一系列的承诺。我想等到它们全部可用,然后取消引用以获取整个向量。
我的实际用例是使用 HTTPKit发出多个并发请求,然后在所有请求返回后处理它们。
收藏品的排序很重要,但在活动结束后可能会被伪造和重新排序。
我目前正在做这样的事情:
(defn parallel-api-query
[queries]
(let [qs (map http/get queries)
bodies (map #(json/read-str (:body @%)) qs)]
bodies))
Run Code Online (Sandbox Code Playgroud)
所有查询都在qs绑定中发出,然后映射将依次阻止每个查询,直到其在map.
这样能达到我想要的结果吗?
由于 Clojure 使用分块序列以及函数处理它们的方式,此实现可能一开始似乎有效,尤其是当您通过传入查询 URL 向量来单独测试该map函数时。但是,您不应该依赖这种行为,因为如果调用代码开始传入一些非分块序列(例如列表,或根据谁知道什么输入计算出的另一个惰性序列),您将失去并行性。
请记住,这map是惰性的,因此绑定qsas(map http/get queries)将产生一个惰性序列,除非强制这样做,否则不会提交请求。返回另一个惰性序列的事实使错误更加复杂,(map #(json/read-str (:body @%)) qs)该序列将处理(惰性)qs序列,提交 API 调用,然后在函数的调用者从返回的序列中请求项目时一次阻塞一个调用。在最坏的情况下,您的 API 请求将按顺序提交。
为了确保并行提交所有请求,并且已收到所有响应,请将对map(请求和 deref)的调用包装在 a 内doall,这将强制评估惰性序列。