【问题标题】:rxjs conditional nesting observablesrxjs 条件嵌套 observables
【发布时间】:2018-11-19 18:33:17
【问题描述】:

我有以下按预期工作的代码:

const sourceObservable = ... // irrelevant
sourceObservable.subscribe(x => {
    doAnyway(x);
    if (x.Id) {             
        doSometing(x);
    } else {
        // id Not set, get default Id
        this.idService.getDefault().subscribe(id => {
            x.Id = id;                  
            doSometing(x);
        });
    }
});

根据this article 嵌套订阅是要避免的。这就是为什么我尝试使用管道重构上面的代码。我尝试使用this Method 实现 if-else 操作,其中过滤用于为每个选项创建一个可观察的分支。最后应该合并订阅。

const obsShared = sourceObservable.pipe(
tap(x => {
    doAnyway(x);
}),
share());

const obsIdNotSet = obsShared.pipe(
    filter(x => !x.kennzahlId),
    merge(x => idService.getDefault().subscribe(id => {
            x.Id = id;
        // doSomething(x) will nomore be executed here
        })));

// even though the true-part is empty I seem to need this to mergeing both options
const obsIdSet = obsShared.pipe( 
    filter(x => !!x.Id),
    tap(() => {
        // doSomething(x) will nomore be executed here
    }));

obsIdSet.pipe(merge(obsIdNotSet)).subscribe(x => {  
    // in case obsIdNotSet this will run with x.Id not set because x.Id will be set later
    doSometing(x);
});

此代码确实编译和运行没有错误,它只在调用idService.getDefault()..... 之前执行doSomething(x),尽管它会在没有设置x.Id 的情况下被调用。

我做错了什么?

【问题讨论】:

标签: angular typescript rxjs


【解决方案1】:

以下是处理该问题的最干净的方法(根据我的说法):

source.pipe(
  tap(val => doAnyway(val)),
  switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
  this.id = id;
  doSomething(id);
});

您可以看到这是多么简短和清晰,并且它与您的第一个代码所做的完全相同。

【讨论】:

  • 如果 this.idService.getDefault() 的结果不是 Id 本身,我能否提供一个映射函数来映射结果?
  • 当然,this.idService.getDefault().pipe(map(...))(你可以在管道中使用管道,这没有问题)
  • 你一定是我的队长 :) 添加了import 'rxjs/add/observable/of';,但似乎找不到。我使用角度 6
  • 没错。为了解释差异,combineLatest 作为静态(不可管道)签名至少需要 2 个 observable,而 combineLatest 作为实例方法只能使用一个(第二个是“管道”第一个 observable)。请参阅this stackblitz 以查看语法差异!
  • 同样,祝你的项目好运! (如果有人想要来源,这一切都来自the documentation!)
猜你喜欢
  • 1970-01-01
  • 2017-08-10
  • 2017-03-20
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
  • 2021-05-10
  • 2020-05-05
  • 2021-02-18
相关资源
最近更新 更多