Angular 我该如何重构这个角度2的可观测值,以避免在路线改变时重复
我有这个工作的罚款为我在目前,如果页面保持静态如下 使用服务获取要重复的计时器上http调用的结果Angular 我该如何重构这个角度2的可观测值,以避免在路线改变时重复,angular,rxjs,angular2-observables,Angular,Rxjs,Angular2 Observables,我有这个工作的罚款为我在目前,如果页面保持静态如下 使用服务获取要重复的计时器上http调用的结果 this.lts.getEventDetails(link,currentTime) .subscribe(res=>{ this.rs.setCurrentRace(activeRound['uid'],res.S); }) 在我的服务中调用此函数 getEventDetails(liveTimingLink:string,time:number){ let lin
this.lts.getEventDetails(link,currentTime)
.subscribe(res=>{
this.rs.setCurrentRace(activeRound['uid'],res.S);
})
在我的服务中调用此函数
getEventDetails(liveTimingLink:string,time:number){
let link = `${liveTimingLink}?R=${time}`
let timer = 5000;
Observable
.interval(timer)
.flatMap(() => {
return this.http.get(link)
.map(res=>{return res.json()})
})
}
问题是每次我改变路线回来时,它都会复制可观察到的计时器
我不确定我应该如何处理这个问题,我想我应该在服务中将observable设置为一个变量,然后返回它,但我不知道我该怎么做
或者我应该像现在这样做,只是随着路线的改变而取消订阅?我也不知道该怎么做
任何建议和想法都是非常受欢迎的。谢谢大家您在方法调用之外创建可观察对象的想法很好 但是。。。每个
.subscribe()
可观察对象接收调用可观察对象的新执行。
这意味着仅仅有一个可观测的实例是不够的。您还需要在所有订阅者之间共享执行
起初,我认为您可以使用操作符,但只要它至少有一个订户,它将只共享可观察的。在您的情况下,它不起作用,因为当用户离开页面时,可观察对象将丢失其唯一订户。下次用户访问页面时,可观察对象需要从头开始重新执行(换句话说,间隔重置)。我怀疑这不是你想要的
我找到了一个解决方案,它使用操作符来共享可观察对象,并.connect()
使其在第一次检索时开始发出值。无论您是否订阅,间隔都会持续运行
看看这个,看看它的行动。订阅/取消订阅按钮复制用户导航到/离开页面时发生的情况。打开浏览器控制台以查看订阅者接收到的值
服务代码:
@Injectable()
类MyService{
//创建一次间隔并在所有订阅者之间共享。
source=Observable.interval(1000).publish();
intervalStarted=false;
getEventDetails(参数){
//第一次检索可观察对象时,
//连接到它(=使它开始发射值)。
如果(!this.intervalStarted){
this.source.connect();
this.intervalStarted=true;
}
//在这里,继续使用诸如mergeMap()之类的运算符变换原始可观察对象。
返回这个.source.map(val=>`${val}-${param}`);
}
}
关于getEventDetails()
方法版本的一些小说明:
- 您可以将
放在箭头函数的主体周围。这样您将得到一个隐式的{}
,您的代码将更加紧凑。不过,为了便于阅读,您可能需要保留您的版本返回
- 如果您使用的是Angular2+,那么您使用的是RxJS 5,“官方”操作符是
mergeMap()
来自RxJS 4,只是flatMap()
的别名mergeMap()
- 由于方法中的局部变量不变,因此可以使用
vsconst
声明它们let
- 为什么在可观察的
之前没有
。间隔返回
getEventDetails(liveTimingLink:string,time:number){
const link=`${liveTimingLink}?R=${time}`;
常数定时器=5000;
可观测回波
.时间间隔(计时器)
.flatMap(()=>this.http.get(link.map)(res=>res.json())
}
我回到这里,感谢您对这个问题的想法和建议,我一直很感谢经验丰富的程序员的反馈
最后,我重新编写了代码,只需取消订阅可观察的路线更改。看起来比较简单,而且照顾到了我的需要
服务:
getEventDetails(liveTimingLink:string,time:number){
const link = `${liveTimingLink}?R=${time}`
const timer = 5000;
return Observable
.interval(timer)
.flatMap(() => {
return this.http.get(link)
.map(res=>{return res.json()})
})
}
组成部分:
saveLiveRaceString(serie:FirebaseObjectObservable<any>,activeRound){
/**
Only map & subscribe if current event has begun.
**/
const currentUnix = moment().unix();
if(currentUnix > activeRound['mainEventUnix'] ){
this.eventSubscription = this.lts.getEventDetails(serie['liveTimingLink'],currentUnix)
.subscribe(res=>{
this.rs.setCurrentRace(activeRound['uid'],res.S);
})
}
}
ngOnDestroy() {
/**
Unsubscribe from the event observable
**/
this.eventSubscription?this.eventSubscription.unsubscribe():null
}
saveLiveRaceString(系列:FirebaseObjectObservable,activeRound){
/**
仅在当前事件已开始时映射和订阅。
**/
const currentUnix=moment().unix();
如果(currentUnix>activeRound['mainEventUnix']){
this.eventSubscription=this.lts.getEventDetails(serie['liveTimingLink',currentUnix)
.订阅(res=>{
这个.rs.setCurrentRace(activeRound['uid'],res.S);
})
}
}
ngOnDestroy(){
/**
取消订阅可观察到的事件
**/
this.eventSubscription?this.eventSubscription.unsubscripte():null
}