如果在 Angular 中满足条件,如何 运行 并停止订阅中的间隔方法
How to run and stop the interval method in the subscribe if condition is met in Angular
这里我有疑问,如何在订阅中调用间隔方法并在满足条件后停止它
下面是我的代码
主要订阅方法
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
})
}
在响应中给出了 3 种类型的响应
继续
停止
终止
所以在这里我需要在 Main subscribe 方法中调用 getInterval() 直到 GetInterval 给我 Proceed 作为响应或者直到轮询 1 分钟后我设置了间隔 运行 如果满足任何一个条件我必须停止投票。
注意:我不需要轮询 Main Subscribe 方法,如果 main subscribe 给出成功的响应,那么只有我开始这个轮询
更新:
下面的方法有效,但这里我需要两件事
如何设置变量并将响应存储在其中
如果有响应,我如何设置基于 res 的布尔变量
this.content =真聪明
因为当我尝试在 switchMap 中设置变量时它不接受
this.authservice.getdata().管道(
switchMap(resp => timer(0, 5000).pipe( // 需要将此响应存储在全局变量中,以便进一步使用
switchMap(t => this.authservice.getIntervalData( <第一个响应参数> ).pipe(
map(data => [data, t]))) takeWhile(([data, t]) => data !== 'TERMINATE' && t < 12),
地图(([数据,t])=>数据)
))
).subscribe(数据=> console.log(数据))
您可能只想使用运算符和可观察值....
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
))
更新:
"stop this interval outside of method i mean like a button click"
clicked$ = new Subject<void>();
onclick(){
this.clicked.next(); // on click emit value
}
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(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);
这会在 60000 毫秒后发出一次,即 1 分钟
接下来我们定义
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
当条件满足时,我们将使用此可观察对象终止计时器,使用 takeUntil
运算符并在可观察对象上调用 next()
函数
我们接着定义
interval$ = timer(0, 5000).pipe(
takeUntil(this.stopTime$),
takeUntil(this.terminateAction$),
);
此 observable 将每 5000 毫秒以 0 延迟发射,直到 stopTime$
observable 被调用或 terminateAction$
被调用
然后我们创建一个主题来存储我们的全局变量。由于 observables 是异步的,为了避免值未定义,使用 observables 来存储我们的变量并在我们需要它们时订阅这个变量是有意义的
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
最后我们定义了我们的区间数据 Observable
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),
tap(res => this.responseSubject$.next({res, content: true})),
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): ''),
)
tap(res => this.responseSubject$.next({res, content: true}))
存放全局变量
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): '')
终止 interval observable
这里我有疑问,如何在订阅中调用间隔方法并在满足条件后停止它
下面是我的代码
主要订阅方法
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
})
}
在响应中给出了 3 种类型的响应
继续
停止
终止
所以在这里我需要在 Main subscribe 方法中调用 getInterval() 直到 GetInterval 给我 Proceed 作为响应或者直到轮询 1 分钟后我设置了间隔 运行 如果满足任何一个条件我必须停止投票。
注意:我不需要轮询 Main Subscribe 方法,如果 main subscribe 给出成功的响应,那么只有我开始这个轮询
更新: 下面的方法有效,但这里我需要两件事
如何设置变量并将响应存储在其中
如果有响应,我如何设置基于 res 的布尔变量
this.content =真聪明
因为当我尝试在 switchMap 中设置变量时它不接受
this.authservice.getdata().管道( switchMap(resp => timer(0, 5000).pipe( // 需要将此响应存储在全局变量中,以便进一步使用 switchMap(t => this.authservice.getIntervalData( <第一个响应参数> ).pipe( map(data => [data, t]))) takeWhile(([data, t]) => data !== 'TERMINATE' && t < 12), 地图(([数据,t])=>数据) )) ).subscribe(数据=> console.log(数据))
您可能只想使用运算符和可观察值....
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
))
更新:
"stop this interval outside of method i mean like a button click"
clicked$ = new Subject<void>();
onclick(){
this.clicked.next(); // on click emit value
}
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(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);
这会在 60000 毫秒后发出一次,即 1 分钟
接下来我们定义
terminateSubject$ = new Subject();
terminateAction$ = this.terminateSubject$.asObservable();
当条件满足时,我们将使用此可观察对象终止计时器,使用 takeUntil
运算符并在可观察对象上调用 next()
函数
我们接着定义
interval$ = timer(0, 5000).pipe(
takeUntil(this.stopTime$),
takeUntil(this.terminateAction$),
);
此 observable 将每 5000 毫秒以 0 延迟发射,直到 stopTime$
observable 被调用或 terminateAction$
被调用
然后我们创建一个主题来存储我们的全局变量。由于 observables 是异步的,为了避免值未定义,使用 observables 来存储我们的变量并在我们需要它们时订阅这个变量是有意义的
responseSubject$ = new Subject()
responseAction$ = this.responseSubject$.asObservable();
最后我们定义了我们的区间数据 Observable
intervalData$ = this.interval$.pipe(
switchMap(() => this.authservice.getIntervalData()),
tap(res => this.responseSubject$.next({res, content: true})),
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): ''),
)
tap(res => this.responseSubject$.next({res, content: true}))
存放全局变量
tap(res => res === 'Terminate' ? this.terminateSubject$.next(true): '')
终止 interval observable