Angular rxjs:定期执行一些操作,其间有特定的延迟
客户端应用程序向服务器发送请求,这可能需要很长时间才能完成。一旦请求完成或失败,客户端应等待一段时间(即10秒),然后再次发送请求 目前的工作解决方案是:Angular rxjs:定期执行一些操作,其间有特定的延迟,angular,rxjs,reactive-programming,Angular,Rxjs,Reactive Programming,客户端应用程序向服务器发送请求,这可能需要很长时间才能完成。一旦请求完成或失败,客户端应等待一段时间(即10秒),然后再次发送请求 目前的工作解决方案是: appRequest=新主题(); ngOnInit():void{ this.appRequest.delay(10000).subscribe(()=>this.refresh()); 这个。刷新(); } 刷新(){ this.api.getApplications().subscribe(a=>{ 这是更新应用程序(a); this.
appRequest=新主题();
ngOnInit():void{
this.appRequest.delay(10000).subscribe(()=>this.refresh());
这个。刷新();
}
刷新(){
this.api.getApplications().subscribe(a=>{
这是更新应用程序(a);
this.appRequest.next();
},()=>this.appRequest.next()
);
}
有没有更优雅的解决方案
编辑:
我可以使用定时,但我不想发送新的请求,除非以前的请求已经完成。只有在前一个请求完成后,我才想等待10秒钟,然后再次发送请求。这应该无限期地重复
getApplications()
函数由swagger生成,它在内部使用angular的http客户端库。当前的观察结果是,除非您订阅由getApplications()
返回的Observable
,否则它不会向服务器发送请求 您正在寻找新的
从上面的链接:
可以使用.expand()
递归调用函数
var recursiveObservable=this.api.getApplications().delay(10000);
//递归调用
递归可观测
.展开((res)=>{
//如果你想的话,你可以用你的资源做点什么。
返回递归可观察;
})
.subscribe();
上述解决方案将:
.expand()
将无限期地重复自身,直到您实际为其提供终止条件为止。例如,可以使用take运算符指定要重复的次数:
recursiveObservable
.展开((res)=>{
//如果你想的话,你可以用你的资源做点什么。
返回递归可观察;
})
.取(10)//重复10次后停止
.subscribe()
或者,终端条件可以仅基于布尔值:
var shouldContinue=true;
递归可观测
.展开((res)=>{
//您可以根据res结果修改shouldContinue。
return shouldContinue?recursiveObservable:Observable.empty();
})//当shouldContinue为false时将终止
.subscribe()
此解决方案仍然使用主题
(并且不止一次),但它不需要其他函数来知道或调用刷新()
:
注:
- 记住使用
,takeUntil
,。。。阻止它。最好在unsubscribe
之前执行mergeMap
takeUntil
解决方案非常优雅,如有可能,应予以考虑。但在您的情况下,它不适合,因为请求必须在出错时重复,如果您的请求返回多个值,它将失败。需要对这些情况进行特殊处理,以使其正常工作expand
使用repeatWhen+delay定期轮询数据:
source.repeatWhen(completed=>completed.delay(5000))
你的版本可能是
stopRequesting=新主题();
恩戈尼尼特(){
this.api.getApplications()
.repeatWhen(已完成=>completed.delay(10000))
.takeUntil(停止请求)
.subscribe(a=>this.updateApplications(a))
}
恩贡德斯特罗(){
this.stopRequesting.next(true);
}
演示
//记录到html输出
log=函数(x){document.write(x+“
”);};
const stop=新的接收对象();
Rx.可观测间隔(500)
.采取(2)
.repeatWhen(已完成=>completed.delay(1000))
.takeUntil(停止)
.订阅(
x=>log(`Next:${x}`),
err=>log(`Error:${err}`),
()=>日志('已完成')
);
setTimeout(()=>stop.next(true),10000)
带有重复
和延迟
的解决方案看起来更容易理解:
unsubscribe = new Subject();
ngOnInit() {
this.api.getApplications()
.pipe(
delay(10000),
repeat(),
takeUntil(this.unsubscribe))
.subscribe(a => this.updateApplications(a))
}
ngOnDestroy() {
this.unsubscribe.next(true);
}
这种方法的问题在于它不会等待前一个请求完成。我需要它等待前一个请求完成,然后等待10秒,然后提出新的请求。这看起来令人兴奋,但不幸的是它不起作用。也许我忘了提到
getApplications()
函数是由swagger生成的,它使用angular的http客户端库。除非我订阅了由getApplications()
提供的observable,否则它甚至不会向服务器发送请求。@Sasa是的,在.expand运算符之后,您需要像往常一样订阅()observable
const retry$ = new Subject();
const autoRetryRequest$ = Observable.of('Kick start')
.merge(retry$)
.mergeMap(() => {
const next$ = new Subject()
this.api.getApplications().delay(10000).subscribe(
value => next$.next(value),
() => retry$.next(),
() => retry$.next()
);
return next$;
})
.subscribe((data) => { this.updateApplications(data); });
unsubscribe = new Subject();
ngOnInit() {
this.api.getApplications()
.pipe(
delay(10000),
repeat(),
takeUntil(this.unsubscribe))
.subscribe(a => this.updateApplications(a))
}
ngOnDestroy() {
this.unsubscribe.next(true);
}