等待 collection 个承诺?
Waiting on a collection of promises?
我有一系列的承诺。我想等到它们都可用,然后取消引用以获取整个向量。
我的实际用例是 using HTTPKit 发出多个并发请求,然后在所有请求都返回时处理它们。
collection 的顺序很重要,但可以在事件发生后伪造 re-ordered。
我目前正在做这样的事情:
(defn parallel-api-query
[queries]
(let [qs (map http/get queries)
bodies (map #(json/read-str (:body @%)) qs)]
bodies))
所有查询都在 qs
绑定中发出,然后地图将依次阻塞每个查询,直到它在 map
中取消引用。
这样会达到我想要的结果吗?
由于 Clojure 对 chunked sequences 的使用以及它们的处理方式,此实现一开始可能看起来有效,特别是如果您通过传入查询 URL 向量来单独测试函数map
函数。但是,您不应该依赖这种行为,因为如果调用代码开始传递一些非分块序列(例如列表,或者根据谁知道什么输入计算的另一个惰性序列),您将失去并行性。
请记住 map
是惰性的,因此将 qs
绑定为 (map http/get queries)
将产生一个 lazy 序列,该序列不会提交请求,直到它被迫这样做。 (map #(json/read-str (:body @%)) qs)
returns 另一个惰性序列将处理(惰性)qs
序列,提交 API 调用,然后一次阻塞它们函数的调用者从返回的序列中请求项目的时间。在最坏的情况下,您的 API 请求将按顺序提交。
为确保您的所有请求都是并行提交的,并且所有响应都已收到,请将对 map
的调用(包括请求和取消引用)包装在 doall
中,这将强制计算惰性序列。
我有一系列的承诺。我想等到它们都可用,然后取消引用以获取整个向量。
我的实际用例是 using HTTPKit 发出多个并发请求,然后在所有请求都返回时处理它们。
collection 的顺序很重要,但可以在事件发生后伪造 re-ordered。
我目前正在做这样的事情:
(defn parallel-api-query
[queries]
(let [qs (map http/get queries)
bodies (map #(json/read-str (:body @%)) qs)]
bodies))
所有查询都在 qs
绑定中发出,然后地图将依次阻塞每个查询,直到它在 map
中取消引用。
这样会达到我想要的结果吗?
由于 Clojure 对 chunked sequences 的使用以及它们的处理方式,此实现一开始可能看起来有效,特别是如果您通过传入查询 URL 向量来单独测试函数map
函数。但是,您不应该依赖这种行为,因为如果调用代码开始传递一些非分块序列(例如列表,或者根据谁知道什么输入计算的另一个惰性序列),您将失去并行性。
请记住 map
是惰性的,因此将 qs
绑定为 (map http/get queries)
将产生一个 lazy 序列,该序列不会提交请求,直到它被迫这样做。 (map #(json/read-str (:body @%)) qs)
returns 另一个惰性序列将处理(惰性)qs
序列,提交 API 调用,然后一次阻塞它们函数的调用者从返回的序列中请求项目的时间。在最坏的情况下,您的 API 请求将按顺序提交。
为确保您的所有请求都是并行提交的,并且所有响应都已收到,请将对 map
的调用(包括请求和取消引用)包装在 doall
中,这将强制计算惰性序列。