使用Swift和PromiseKit链接Alamofire请求

时间:2017-09-29 23:59:47

标签: json swift promise alamofire promisekit

我有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调用,并成功地为每个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 个答案:

答案 0 :(得分:0)

您需要使用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)
    }