使用 Swift 和 PromiseKit 链接 Alamofire 请求
Posted
技术标签:
【中文标题】使用 Swift 和 PromiseKit 链接 Alamofire 请求【英文标题】:Chaining Alamofire requests with Swift and PromiseKit 【发布时间】:2017-09-29 23:59:47 【问题描述】:我有 2 个 API 端点;后者取决于前者的结果。
第一个端点是/api/v1/regions/
,它像这样返回一个区域JSON列表
region_id: 1,
mayor_id: 9
,
region_id: 1,
mayor_id: 10
,
第二个端点是/api/v1/mayor/<id>/
,它返回一个关于市长的 JSON。我现在的工作流程是进行第一个 API 调用以获取所有区域,然后我想根据从第一个端点获得的 ID 对 /mayor/
端点进行一堆 API 调用。所以在这个例子中,我想再打 2 个电话:
/api/v1/mayor/9/
/api/v1/mayor/10/
我已经设置了 2 个函数来进行每个 API 调用,并成功地为每个函数取回 JSON。
func fetchRegions() -> Promise<[Region]>
func fetchMayor(id: String) -> Promise<Mayor>
现在我想看看如何将所有这些链接在一起。这是我目前所拥有的:
var fetchedRegions: [Region] = []
firstly
fetchRegions()
.then regions in
fetchedRegions = regions
.then
for r in fetchedRegions
self.fetchMayor(id: r.mayor_id).then mayor in
print(mayor)
.catch error in
.catch error in // Error: Missing return in a closure expected to return 'AnyPromise'
print(error)
【问题讨论】:
【参考方案1】:您需要使用when(fulfilled:)
运算符。它等待集合中的所有承诺都实现。
when(fulfilled: promise1, promise2).then results in
//…
.catch error in
switch error
case URLError.notConnectedToInternet:
//…
case CLError.denied:
//…
注意:
如果任何提供的 Promise 被拒绝,返回的 Promise 会立即被拒绝并显示该错误。 警告:
在被拒绝的情况下,其他承诺将继续解决,并且根据任何其他承诺,将履行或拒绝。这是 getter 风格异步任务的正确模式,但通常对于 setter 任务(例如,将数据存储在服务器上),您很可能需要等待所有任务,然后根据哪些成功和哪些失败采取行动,在这种情况使用when(resolved:)
。
根据您的示例,它看起来如下(我明确定义了所有输入/输出参数):
fetchRegions() // fetch your regions async
.then (regions: [Region]) -> Promise<[Mayor]> in // here you got array [Region]
var tasks: [Promise<Mayor>] = [] // create an array of promises to fetch 'Mayor'
for region in regions
tasks.append(self.fetchMayor(id: region.mayorId))
return when(fulfilled: tasks) // create promise which wait for all promises in a set to fulfill
.then (mayours: [Mayor]) -> Void in // here you will get an array of `Mayor`
// do here you want
.catch error in
print(error)
【讨论】:
以上是关于使用 Swift 和 PromiseKit 链接 Alamofire 请求的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中使用 PromiseKit 和 Firebase?
PromiseKit 和 CloudKit 保存(使用 Swift)
While Loop 在 Promisekit 完成运行并在 Swift 中返回正确的值之前递增并重新运行