订阅另一个订阅处理程序中的observable是否合适?

时间:2017-06-30 08:35:27

标签: rxjs observable

我正在使用Angular2,我有一个问题,如果我有很多可观察量,最好的方法是什么。 我可以将订阅放在彼此内部,也可以将每个订阅放在不同的方法中,并将结果放在类属性中吗?

示例:

ngOnInit() {
this.route.params**.subscribe**(params => {
   if (params['id']) {
    this.load = true;
     this.batchService.getPagesOfCurrentObject(params['id'], "10", "0")
       **.subscribe**(result => {
         this.stream = result;
         if (this.stream.length > 0) {
           this.stream.forEach(page => { this.batchService.getPageStreamById
           (page.pageId)**.subscribe**(pageStream => {
              let base64 = btoa(new Uint8Array(pageStream.data)
                 .reduce((data, byte) 
                    => data + String.fromCharCode(byte), ''));
               this.pages.push(base64 );

             })

             return;
           });
         }

     },
       error => this.errorService.setError(<any>error),
       () => this.load = false
       );
   }
 });

 try {
   this.customer = this.sharedService.processSelect.subscription.customer;
 } catch (err) {
   return;
 }
}

1 个答案:

答案 0 :(得分:4)

有多个observable是完全没问题的,这就是反应式编程的意思:)

但是你的问题是subscribe太多了。请记住subscribe是一种产生副作用的方法。要获得易于阅读的代码,您应该尝试使用尽可能少的subscribe

您的用例是mergeMap运算符的完美用例,它允许您展平嵌套的observable。

这是您的代码的样子

const response$ = this.route.params
  .mergeMap(params => {
    return this.batchService.getPagesOfCurrentObject(params['id'])
  })
  .mergeMap(stream => {
    return Rx.Observable.merge(stream.map(page => this.batchService.getPageStreamById(page.pageId))
  })
  .map(pageStream => /* do your stuff with pageStream, base64 ... */)

response$.subscribe(pageStreamData => pages.push(pageStreamData))

了解如何触发会影响应用状态的副作用的单一订阅

请注意,我自愿简化了代码(删除了错误处理和检查),以便了解如何执行此操作。

我希望它能帮助你思考反应式编程:)