问题描述
在这里我有一个查询,如何在订阅中调用间隔方法,并在满足条件后将其停止
下面是我的代码
this.authservice.getdata().subscribe(response => {
console.log(res)
// Polling method
SetInterval(()=>{
this.getInterval();
},5000)
})
间隔方法:
getInterval(){
this.authservice.getIntervalData().subscribe(resp => {
console.log(resp)
this.responseStatus = resp
})
}
在响应中,它给出了三种响应类型
继续
停止
终结
因此,在这里我需要在Main subscription方法中调用该getInterval(),直到GetInterval给我继续作为响应,或者直到从轮询开始1分钟为止,如果满足上述两个条件之一,我都必须设置运行间隔,我必须停止轮询。
注意:如果主订阅在成功后给出响应,那么我不需要对主订阅方法进行轮询
-
如何设置变量并在其中存储响应
-
我如何根据响应来设置布尔变量,例如响应是否到来
this.content = true明智
因为当我尝试在switchMap中设置变量时,它不接受
this.authservice.getdata()。pipe( switchMap(resp => timer(0,5000).pipe(//需要将此响应存储在全局变量中,以便可以将其用于进一步 switchMap(t => this.authservice.getIntervalData().pipe( map(data => [data,t])))takeWhile(([[data,t])=> data!=='TERMINATE'&& t 数据) )) ).subscribe(data => console.log(data))
解决方法
您可能只想使用运算符和可观察对象...。
this.authservice.getdata().pipe( // get initial data
tap(resp => this.myVariable = resp),switchMap(resp => timer(0,5000).pipe( // switch to timer that emits every 5 seconds
switchMap(t => this.authservice.getIntervalData().pipe( // swtich again to interval data
map(data => [data,t]))) // map to response and timer value
takeWhile(([data,t]) => data !== 'TERMINATE' && t < 12),// whatever stop condition,this says stop when the data is terminate or the timer has emitted 12 times (1 minute if emitting every 5 seconds)
map(([data,t]) => data) // just send the data through
))
).subscribe(data => console.log(data))
类似的东西就是我要实现的方式。
,考虑实现它,如下所示:
this.authservice.getdata().pipe(
tap(x => this.globalVariable = x),switchMap(data => interval(5000).pipe(
switchMap(x => this.authservice.getIntervalData(x)),//<== pass data from first subscription to second
takeUntil(timer(60 * 1000)),takeWhile(x => x !== 'TERMINATE'),map(data2 => [data,data2]) // <= return values from both subscriptions
))
更新:
“在方法之外停止此间隔,我的意思是像单击按钮一样”
clicked$ = new Subject<void>();
onclick(){
this.clicked.next(); // on click emit value
}
this.authservice.getdata().pipe(
tap(x => this.globalVariable = x),map(intervalDataRes => this.condition = intervalDataRes),takeUntil(merge(this.clicked$,timer(2 * 60 * 1000))) // interval will stop after 2 or as soon as clicked$ emits
))
,
考虑使用Subject
存储全局变量。这样,您将避免完全订阅
以下解决方案已在stackblitz see this link
上进行了测试 // Emit Once after 60 Seconds
stopTime$ = timer(60000);
// TerminateResponse
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
// Emits Every 5 seconds until stopTime is called
interval$ = timer(0,5000).pipe(
takeUntil(this.stopTime$),takeUntil(this.terminateAction$),);
// Global Variable
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
// Create Interval Observable. This will call getIntervalData until no more interval
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),tap(res => this.responseSubject$.next({res,content: true})),tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): ''),)
我们定义了一个变量
stopTime$ = timer(60000);
它在60000ms之后发射一次,即1Min
接下来我们定义
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
当使用takeUntil
运算符并在可观察对象上调用next()
函数满足条件时,我们将使用此可观察对象来终止计时器
然后我们定义
interval$ = timer(0,);
此可观察对象每5000毫秒发射0延迟,直到调用stopTime$
可观察对象或调用terminateAction$
为止
然后,我们创建一个主题来存储我们的全局变量。由于可观察变量是异步的,因此为了避免值未定义,使用可观察变量来存储我们的变量并在需要它们时订阅该变量将很有意义
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
最后,我们定义间隔数据可观察
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),)
tap(res => this.responseSubject$.next({res,content: true}))
存储全局变量
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): '')
终止可观察的时间间隔