使用combineAll替换switchMap和map?

时间:2017-08-07 14:56:43

标签: typescript rxjs observable angular2-services side-effects

我尝试使用combineAll来组合所有,我尝试了不同的组合但却无法使用它。 但我设法通过使用所有这些switchMap / map进行这种丑陋的嵌套来获得一些工作代码。 如何使用combineAll获得相同的结果?

@Effect()
  SelectItem$: Observable<Action> = this.actions$
    .ofType(supernode.ActionTypes.SET_SELECTED_ITEM)
    .debounceTime(100)
    .switchMap(() => {
      return this.itemService.isEditable().switchMap(
        edit => this.itemService.isSharable().switchMap(
          share => this.itemService.isListable().map(
            list => new item.SetShareStatus({
              listable: list, editable: edit, sharable: share
            })
          )
        )
      ).take(1);
    })
    .catch(this.handleError);

2 个答案:

答案 0 :(得分:2)

我建议改为使用combineLatest运算符:

...
.switchMap(() =>
    Observable.combineLatest(
        this.itemService.isEditable(),
        this.itemService.isSharable(),
        this.itemService.isListable(),
        (editable, sharable, listable) =>
            new SetShareStatus({ editable, sharable, listable })
    )
    .take(1)
)

combineAll应该应用于更高阶的observable,即可观察到的observable,所以如果你真的想要使用它,那么你需要首先从你的observable中创建一个更高阶的observable ,例如:

Observable.of(
    this.itemService.isEditable(),
    this.itemService.isSharable(),
    this.itemService.isListable()
)
.combineAll((editable, sharable, listable) =>
    new SetShareStatus({ editable, sharable, listable }))

答案 1 :(得分:2)

我不确定您调用的所有功能应该做什么,但在我看来,您不需要同时使用combineAllswitchMap。我认为您可以使用zip()forkJoin()

做得更好
.switchMap(() => Observable.forkJoin(
    this.itemService.isEditable()
    this.itemService.isSharable()
    this.itemService.isListable()
  ))
  .map(results => new SetShareStatus({
    listable: results[2], editable: results[1], sharable: results[1]
   }))
})

我认为combineLatest()不是一个不错的选择,因为当它的任何源Observable发出时它会发出,我认为你不想要它。