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

时间:2016-12-28 12:09:23

标签: angular rxjs rxjs5

我的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())?

2 个答案:

答案 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