具有超时和检查 RxJs 可观察值轮询的递归函数 [英] Recursive function with timeout and check RxJs Observable value polling
问题描述
我有递归函数:repeatAlert
,如果data.answered === null
:
I have the recursive function: repeatAlert
that is called again if data.answered === null
:
....编辑
this.repeatAlert(id).subscribe( val => console.log(val));
console.log('1stCall Alert: ', new Date().getMinutes());
....
find(id: number): Observable<any> {
return this.http.get(`${this.resourceUrl}ByAlertId/${id}`
}
repeatAlert(id: number) {
this.find(id).subscribe((data: AlertInt) => {
if (data.answered === null ) {
this.sendNotification('Alert ', data.text);
console.log('Call Alert: ', new Date().getMinutes(), data.id);
setTimeout(() => {
if (data.answered === null) {
this.repeatAlert(id);
}
}, data.repeating * 1000 * 60);
}
});
}
当我改变数据库中data.answered
的值时,我无法用这个可观察的find(id)
读取data的变化.回答
.所以它一直在调用 repeatAlert
永远......
When I change the value of data.answered
in the database, I can't read with this observable find(id)
the change of data.answered
. So it keeps calling repeatAlert
forever ...
我做错了什么?
额外问题:循环还是递归函数更好?
Extra question: Is it better a loop or recursive function ?
推荐答案
您正在进行投票.我建议如下:
You are doing polling. I suggest something like following:
find(id: number): Observable<any> {
return this.http.get(`${this.resourceUrl}ByAlertId/${id}`;
}
repeatAlert(id: number) {
// request data from the endpoint and execute necessary code
const data$ = this.find(id).pipe(
tap(data => {
if (data.answered === null) {
this.sendNotification('Alert ', data.text);
}
})
);
// polling will start if on the first try we don't have data.answered
const startPolling = (duration: number) => timer(duration, duration).pipe(
//take(10), // let's say we want to stop after 10 tries
concatMap(() => data$),
takeWhile(data => data.answered === null), // when to stop polling
);
// if data.answered is null on the first try switch to polling otherwise end
return data$.pipe(
switchMap(data => data.answered === null ?
startPolling(data.repeating * 1000 * 60) :
of(data)
),
);
}
另请注意,我更改了您的repeatAlert
,最好从方法返回 Observable 并自己订阅以避免内存泄漏.您应该自己订阅和取消订阅.另外,我建议您使用 take(10)
为例,以便轮询不会无限期地继续,这取决于您.
Also note that I changed your repeatAlert
, it's better to return Observable from the method and subscribe yourself to avoid memory leaks. You should subscribe and unsubscribe yourself. Also, I suggest you to use take(10)
for example so that polling doesn't continue indefinitely, it's up to you.
timer(dueTime, period)
的工作原理如下: 它会在 dueTime
之后发出第一个事件,并在每个 之后继续发出事件期间
.
timer(dueTime, period)
works like this: It will emit first event after dueTime
and continue emitting events after every period
.
编辑 takeWhile 条件为真而非条件为假
Edit takeWhile condition is true and not condition is false
这篇关于具有超时和检查 RxJs 可观察值轮询的递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!