我有2订阅角/ typescript 项目。
这2个订阅订阅它们自己的可观察的A
和B
,它们在组件外部并且在服务文件中。
有时,基于某些组件动作,A
改变,而B
可能不改变,反之亦然,然而,通常B
在另一组件中的A
改变之后改变
此外,B
必须在检查A
的值是否正确之后才能执行操作,因此我所能想到的是使用if语句的嵌套订阅,如下所示。
ngOnInit(){
this.A = this.serviceX.a.subscribe(
data =>{
this.temp = data;
if(data=='correct'){
this.B = this.serviceX.b.subscribe(
beta => {
console.log('Sure'+this.temp);
}
)
}
}
)
}
当它工作的时候?但是我看到其他的帖子说这不是一个好的方法。所以我尝试了combineLatest
和forkJoin
。但是看起来他们只有在两个可观察的改变的时候才工作。并且如果其中一个可观察的根本没有改变,他们将不会被调用。如果我错了请纠正我。
所以现在所有我能想到的是单独订阅和订阅他们一个接一个像下面。
this.A = this.serviceX.a.subscribe(
data =>{
this.temp = data ;
}
)
this.B = this.serviceX.b.subscribe(
beta =>{
if(this.temp=='correct'){
console.log('Sure'+this.temp)
}
}
)
但是我非常担心我做错了,并且做了一个不稳定的迭代。我可以使用什么样的rxjs操作符来确保B订阅只在订阅A完成更改后订阅(然而A可能有时不会更改)?并最终使整个过程更健壮?
3条答案
按热度按时间jhkqcmku1#
在subscribe处理程序中进行订阅可能会很麻烦,我相信这是可以避免的,而且应该永远避免。您的基本工作流程--就我对代码的理解而言--是这样的:
1.从
serviceX.a
检索数据1.将数据存储为副作用
1.如果数据满足某些条件,则从
serviceX.b
检索数据1.实际用户处理程序
现在你可以为每一步查找一个合适的操作符了,我是这样做的:
注意1:您只需要一个订阅。
注2:根据您的使用情况,您可能需要将
concatMap
替换为switchMap
、exhaustMap
或mergeMap
。注三:在这里使用
temp
是相当危险的。根据您选择的*map
运算符,您可能会创建一个竞态条件。在您等待serviceX.b
发出时,serviceX.a
可能已经发出下一个值并覆盖temp
。如果temp
的唯一原因是存储serviceX.a
的结果,您应该使用以下解决方案:Is there an operator that lets me keep the initial value from a subscription after executing ,, switchMap"?vltsax252#
也许你正在寻找
flatMap
,你可以Map多个订阅,每个flatMap
应该返回它自己的Observable
,并只订阅结束。eqqqjvef3#
在另一个订阅中调用
subscribe
是一个不好的做法,因为您中断了流并从另一个流开始(在您的示例中,内部的订阅者从未被销毁,这可能会导致内存问题,每次流进入A时您都创建一个新的订阅者B,而此.B.Unsubscribe只销毁最后一个订阅者)。然后,您需要继续使用
mergeMap
或switchMap
运算符管理Stream,并在最后仅调用一个Subscribe。为了过滤你的流,你可以使用
filter
操作符。之后,你只有1个订户,你需要取消订阅。