PromiseKit 6:如何创建多个并发 Promise 并将它们各自的结果分组到一个数组中?
Posted
技术标签:
【中文标题】PromiseKit 6:如何创建多个并发 Promise 并将它们各自的结果分组到一个数组中?【英文标题】:PromiseKit 6: How to create multiple concurrent promises and group their individual results into an array? 【发布时间】:2018-09-06 23:21:48 【问题描述】:我正在处理一个奇怪的 API,我在其中收到一个 ID 列表,我需要单独请求每个 ID 的数据。我不需要一个接一个地链接这些请求,我只想一次获取它们,但我无法弄清楚如何以干净的方式执行此操作。
我已经制定了获取一个 ID 的方法,它会生成一个Promise<DataObject>
。如何将我的 ID 数组转换为一组 promise,然后给我 [DataObject]
func fetchDataObject(_ id: Int64) -> Promise<DataObject>
return makeURL("\(id)")
.then
URLSession.shared.dataTask(.promise, with: $0)
.compactMap (data, response) -> DataObject in
// ...
return try decoder.decode(DataObject.self, from: data)
// get the list of IDs and turn them into DataObjects
func fetchNew() -> Promise<[DataObject]> // desired output
return makeURL("all_ids").then
URLSession.shared.dataTask(.promise, with: $0)
.compactMap (data, response) -> [Int64] in
// ...
return try decoder.decode([Int64].self, from: data)
.then( (ids) -> [DataObject] in
// now what???
)
我想我应该使用.when
,但我找不到一个明确的选择来选择哪个方法签名......以及如何创建一组要传递的承诺。
【问题讨论】:
从概念上讲,您正在寻找all
,但是,通过阅读FAQ,PromiseKit 将其称为when
,这会将您带回CookBook 的示例。这可能只允许您传递少量请求(例如 2-3 个),但我不再使用 PromiseKit(当我第一次尝试时它有点错误)并改为移动到 Hydra 所以我我只是猜测
【参考方案1】:
这是你的答案,但按照“更清洁”的要求。
func fetchObjects() -> Promise<[DataObject]>
return firstly
makeURL("all_ids")
.then
URLSession.shared.dataTask(.promise, with: $0).validate()
.map
try decoder.decode([Int64].self, from: $0.data)
.thenMap
self.fetchDataObject($0)
关键变化是thenMap
,它将承诺应用于返回Promise<[T]>
的序列的每个元素。
还使用 Swift 单行闭包语法来删除不会增加太多价值的返回值和参数名称。
firstly
让阅读链更清晰。
如果 HTTP 返回非 2xx 响应,则在 URLSession
承诺上使用 validate()
以拒绝链。
将compactMap
替换为map
,因为decode()
不会返回可选值。
【讨论】:
谢谢,我有不同的问题,但无法弄清楚“.thenMap”部分。你的回答也解决了我的问题!【参考方案2】:好的,我得到了一些有用的东西,我现在更好地理解 then
和 when(fulfilled:)
。
您需要在您的then
中返回when
。
func fetchObjects() -> Promise<[DataObject]>
return makeURL("all_ids")
.then
URLSession.shared.dataTask(.promise, with: $0)
.compactMap (data, response) -> [Int64] in
// ..
return try decoder.decode([Int64].self, from: data)
.then (ids) -> Promise<[DataObject]> in
var requests: [Promise<DataObject>] = []
for id in ids
requests.append(self.fetchDataObject(id))
return when(fulfilled: requests)
【讨论】:
以上是关于PromiseKit 6:如何创建多个并发 Promise 并将它们各自的结果分组到一个数组中?的主要内容,如果未能解决你的问题,请参考以下文章