我的Angular 2应用程序在服务中有2个方法(GetCategories()
和GetCartItems()
),这两个方法都返回Observable
个。
为了从我的组件中一个接一个地调用这两个方法,我写了下面的代码:
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)}
})
});
}
基本上,从GetCartItems()
的{{1}}内拨打subscribe()
,我觉得这不是正确的做法。这是一种回调地狱。
如何以更好的方式实现这一点(例如在GetCategories()
中链接then()
)?
答案 0 :(得分:15)
看起来GetCategories
看起来不依赖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;
});
。然后,您可以使用zip:
char (*p)[sizeof(c)];
^ p... (hit ')', turn around)
^ is a pointer... (hit '(', turn around and remove '()')
^^^^^^^^^^^ to an array of `sizeof(c)`... (end of line, turn around)
^^^^ chars. nothing left, we're done!
答案 1 :(得分:7)
这通常使用concat()
,concatMap()
或最终concatAll()
完成,具体取决于您的使用情况,以及您是否需要按顺序调用这两项服务。
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'));
打印到控制台:
start...
GetCategories()
GetCartItems()
done
每个项目都会延迟显示,这些项目将按顺序逐个调用。
如果您不需要保留相同的订单,则可以使用merge()
或mergeMap()
。
查看现场演示:https://jsbin.com/wawajob/1/edit
请注意,使用zip()
可能会产生不良行为。见https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/zip.md