【发布时间】:2019-03-03 22:57:28
【问题描述】:
我有一组 observables 作为数据存储,我想确保那些热的不会过时。例如,如果没有可观察的订阅者,那么我不需要更新它,但如果有订阅者,那么它不应该超过 5 分钟没有更新。
timeout 似乎是我想要的,但我不希望它出错,我只想在超时时运行代码(类似于tap)。 timeoutwith 更接近,因为我可以用 observable 替换它。但是,它似乎并不“正确”,并且在一次超时后,替换的 observable 将不会附加 timeoutWidth 运算符。
function getData(index){
return database[index].pipe(timeoutWith(5*60*1000, database[index]))
}
我刚刚想到的一种方法是添加递归addTimeout 方法,但这感觉很hacky:
private addTimeout(obs:Observable<any>, time:number):Observable<any>{
return obs.pipe(timeoutWith(time,this.addTimeout(obs,time)));
}
编辑,使用超时/重试添加代码:
const staleDataTime = 5*60*1000; // 5 minutes
// bhs makes it so you can update the value manually whenever you want
let bhs = new BehaviorSubject<Summary>(initialSummary);
// This will reset bhs after the timeout
bhs.pipe(timeout(staleDataTime)).subscribe(success=>null,err=>bhs.next(null));
let obs = bhs.pipe(
switchMap(val=>val?of(val):this.retreiveSummary(filter)),
timeout(staleDataTime),
retry(),
distinctUntilChanged((a:Summary,b:Summary) => a.count==b.count && a.sum == b.sum),
share()
);
obs.subscribe(val=>console.log("obs val: ", val));
【问题讨论】: