Mon Angular 2 possède 2 méthodes (GetCategories()
et GetCartItems()
) dans un service, et ces deux méthodes renvoient Observable
s.
Afin d'invoquer ces deux méthodes l'une après l'autre depuis mon composant, j'ai écrit ci-dessous le code:
ngOnInit()
{
this.appService.GetCategories().subscribe( (data) => {
this.appService.categories = data;
this.appService.GetCartItems().subscribe( {
next: (data) => { this.appService.cart = data},
error: (err) => { this.toaster.error('cart==>' + err)}
})
});
}
Fondamentalement, appeler GetCartItems()
de l'intérieur subscribe()
de GetCategories()
, et je pense que ce n'est pas la bonne approche. C'est une sorte d'enfer de rappel.
Avez-vous une idée de la meilleure façon de l'implémenter (comme chaîner then()
dans Promise
s)?
On dirait que GetCartItems
ne dépend pas de GetCategories
. Ensuite, vous pouvez utiliser Zip :
Observable
.Zip(
this.appService.GetCategories()
this.appService.GetCartItems()
)
.catch(err => this.toaster.error(err))
.subscribe(([categories, cartItems]) => {
this.appService.categories = categories;
this.appService.cart = cartItems;
});
Cela se fait le plus souvent avec concat()
, concatMap()
ou éventuellement concatAll()
selon votre cas d'utilisation et si vous devez appeler les deux services dans l'ordre ou non.
function GetCategories() {
return Observable.timer(1000).do(() => console.log('GetCategories()'));
}
function GetCartItems() {
return Observable.timer(1000).do(() => console.log('GetCartItems()'));
}
console.log('start...');
GetCategories()
.concatMap(() => GetCartItems())
.subscribe(() => console.log('done'));
Cela imprime sur la console:
start...
GetCategories()
GetCartItems()
done
Chaque élément est retardé pour montrer qu'ils sont appelés dans l'ordre l'un après l'autre.
Si vous n'avez pas besoin de conserver le même ordre, vous pouvez utiliser merge()
ou mergeMap()
.
Voir la démo en direct: https://jsbin.com/wawajob/1/edit
Notez que l'utilisation de Zip()
peut avoir un comportement indésirable. Voir https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/Zip.md