我有下面的代码可以正常工作:
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);
});
此代码可以编译并运行而不会出错,只是在调用doSomething(x)
之前执行idService.getDefault().....
,尽管会在未设置x.Id的情况下被调用。
我在做什么错了?
答案 0 :(得分:4)
以下是处理该问题的最干净方法(根据我的说法):
source.pipe(
tap(val => doAnyway(val)),
switchMap(val => val.id ? of(val.id) : this.idService.getDefault())
).subscribe(id => {
this.id = id;
doSomething(id);
});
您可以看到它有多短和清晰,并且它执行的代码与您的第一个代码完全相同。