使用 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 中返回正确的值之前递增并重新运行

使用 Alamofire 和 PromiseKit 使用 Swift 时出现 Void 错误(请求)

Swift 4 - 使用 PromiseKit 调用嵌套

使用带有 Swift 标准网络的 PromiseKit 处理拒绝?