等待一系列承诺?

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.

这样能达到我想要的结果吗?

Ale*_*lex 5

由于 Clojure 使用分块序列以及函数处理它们的方式,此实现可能一开始似乎有效,尤其是当您通过传入查询 URL 向量来单独测试该map函数时。但是,您不应该依赖这种行为,因为如果调用代码开始传入一些非分块序列(例如列表,或根据谁知道什么输入计算出的另一个惰性序列),您将失去并行性。

请记住,这map是惰性的,因此绑定qsas(map http/get queries)将产生一个惰性序列,除非强制这样做,否则不会提交请求。返回另一个惰性序列的事实使错误更加复杂,(map #(json/read-str (:body @%)) qs)该序列将处理(惰性)qs序列,提交 API 调用,然后在函数的调用者从返回的序列中请求项目时一次阻塞一个调用。在最坏的情况下,您的 API 请求将按顺序提交。

为了确保并行提交所有请求,并且已收到所有响应,请将对map(请求和 deref)的调用包装在 a 内doall,这将强制评估惰性序列。