订阅多个 Observables(比如在 Promises 中链接 then())

Subscribe to multiple Observables (like chaining then() in Promises)

我的 Angular2 应用程序在服务中有 2 个方法(GetCategories()GetCartItems()),并且这两个方法 return Observables。

为了从我的组件中依次调用这两个方法,我编写了以下代码:

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

                                                })

   });       
}

基本上,从 GetCategories()subscribe() 中调用 GetCartItems(),我觉得这不是正确的方法。这是一种回调地狱。

关于如何以更好的方式实现它的任何想法(比如在 Promise 中链接 then())?

看起来 GetCartItems 不依赖于 GetCategories。然后你可以使用 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;
    });

这通常是通过 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