Luc*_*key 2 rxjs typescript angular
我有以下代码可以正常工作:
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);
});
}
});
Run Code Online (Sandbox Code Playgroud)
根据本文,嵌套订阅是要避免的。这就是为什么我尝试使用管道重构上述代码的原因。我尝试使用此方法实现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);
});
Run Code Online (Sandbox Code Playgroud)
该代码可以编译并运行,不会出错,仅doSomething(x)在调用之前执行idService.getDefault().....,尽管在未设置x.Id的情况下将被调用。
我究竟做错了什么?
小智 5
以下是处理此问题的最干净方法(根据我的说法):
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
Run Code Online (Sandbox Code Playgroud)
您可以看到这是多么简短,而且很清楚,它与您的第一个代码所做的完全相同。