2017-09-29 2 views
0

J'ai 2 points de terminaison API; ce dernier dépend du résultat du premier.Chaînage de requêtes Alamofire avec Swift et PromiseKit

Le premier point d'extrémité est /api/v1/regions/, qui renvoie une liste de région JSON comme si

{ 
    region_id: 1, 
    mayor_id: 9 
}, 
{ 
    region_id: 1, 
    mayor_id: 10 
}, 

Le deuxième point d'extrémité est /api/v1/mayor/<id>/, qui renvoie un JSON sur le maire. Mon flux de travail est actuellement de faire le premier appel API pour obtenir toutes les régions, puis je veux faire un tas d'appels API au point de terminaison /mayor/ en fonction des ID que je reçois à partir du premier point de fin. Donc, dans cet exemple, je voudrais faire 2 autres appels:

/api/v1/mayor/9/ 
/api/v1/mayor/10/ 

je l'ai déjà mis en place 2 fonctions pour faire de chaque appel d'API et a obtenu avec succès le retour JSON pour chacun.

func fetchRegions() -> Promise<[Region]> { 
} 

func fetchMayor(id: String) -> Promise<Mayor> { 
} 

Maintenant, je voudrais voir comment je pouvais chaîne tout cela ensemble. C'est ce que j'ai jusqu'à présent:

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) 
} 

Répondre

0

Vous devez utiliser l'opérateur when(fulfilled:). Il attend que toutes les promesses dans un ensemble s'accomplissent.

when(fulfilled: promise1, promise2).then { results in 
    //… 
}.catch { error in 
    switch error { 
    case URLError.notConnectedToInternet: 
    //… 
    case CLError.denied: 
    //… 
    } 
} 

Note: Si l'une des promesses fournies Rejeter, la promesse de retour est immédiatement rejeté avec cette erreur.
Avertissement: En cas de rejet, les autres promesses continueront à être résolues et, conformément à toute autre promesse, seront soit satisfaites, soit rejetées. C'est le bon modèle pour les tâches asynchrones de type getter, mais souvent pour les tâches de setter (par exemple, stocker des données sur un serveur), vous devrez probablement attendre toutes les tâches et agir sur celles qui ont échoué, de telles situations utilisent when(resolved:).

En fonction de votre exemple, il semble (I explicitement défini tous les paramètres/sortie):

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) 
    }