我有一个连续发出值的函数。
我想要什么?
如果满足Math.sign条件,我将用户重定向到另一个屏幕并显示一条敬酒消息。
但是现在,由于间隔是连续的,所以连续显示吐司消息。
我尝试了什么?
this.subscription.unsubscribe()
处于if(Math.sign)
条件下,但无效。
任何建议如何在以下代码中停止间隔?
startTimer(validUntil: string) {
this.counter$ = interval(1000).pipe(
map((x) => {
this.diff = Math.floor((new Date(validUntil).getTime() - new Date().getTime()) / 1000);
if (Math.sign(this.diff) == -1) {
//Tried this.subscription.unsubscribe() here
// Redirects me to another component
this.goBack(true);
}
return x;
}));
this.subscription = this.counter$
.subscribe((x) => {
this.message$ = this.dhms(this.diff);
});
}
goBack(requestExpired: boolean) {
if (requestExpired == true) {
this.messageDialogService.presentToast('Expired')
}
this.router.navigate(['mypage']);
}
答案 0 :(得分:1)
您是否尝试过用"?"
方法退订?
答案 1 :(得分:1)
Imho,takeWhile
里面有条件是最明显的方法。
例如:
startTimer(validUntil) {
this.counter$ = interval(1000).pipe(
// turn value emissions into diffs
map(() => Math.floor((new Date(validUntil).getTime() - new Date().getTime()) / 1000)),
// this is needed to terminate when condition is met
takeWhile(diff => Math.sign(diff) !== -1),
// when terminated on conditions -- navigate back
finalize(()=>{
this.goBack(true);
})
// just in case if user navigates out before condition is met
takeUntil(this.destroy$)
)
.subscribe(diff => {
this.message$ = this.dhms(diff);
});
}
注意:但是,我怀疑您根本不需要counter$
。您只能将message$
流与异步管道一起使用,例如
控制器
startTimer(validUntil) {
this.messages$ = interval(1000).pipe(
// ...
)
}
模板
<div>{ messages$ | async }</div>
希望这会有所帮助
答案 2 :(得分:1)
我认为最好的方法是使用takeUntil
管道。
看this example。
我使用takeUntil
和filter
管道重写了您的代码。然后,我将goBack
函数移到了订阅函数的complete
回调中。
startTimer(validUntil: string) {
this.counter$ = interval(1000);
const takeUntil$ = this.counter$.pipe(
filter(x => {
this.diff = Math.floor((new Date(validUntil).getTime() - Date.now()) / 1000);
return Math.sign(this.diff) === -1;
})
);
this.counter$.pipe(takeUntil(takeUntil$)).subscribe(
x => {
this.message$ = this.dhms(this.diff);
},
undefined,
() => {
this.goBack(true);
}
);
}
答案 3 :(得分:0)
据我所知,interval
函数在退订后停止发出,我还创建了一个stackblitz example进行演示。
由于某种原因,您的代码未调用unsubscribe
方法,建议您在此处查找问题,也许在调用unsubscribe
之前先添加调试器,以检查其是否确实存在被执行。
还要检查您是否在正确的对象上调用unsubscribe
,例如,它必须是 subscription ,而不是 timer $ 。
但是我认为毫无疑问,问题出在您显示的代码中。
答案 4 :(得分:0)
实际上,您似乎需要为给定持续时间设置计时器,请尝试
timer(0, 1000).pipe(
take(N)
)
其中N
是当前时间与validUntil
之间的秒数差。所以
startTimer(validUntil) {
// duration in seconds till invalid
const duration = Math.floor((new Date(validUntil).getTime() - Date.now()) / 1000));
this.messages$ = timer(0, 1000).pipe(
// we take 1 more emission to encompass starting emission
take(duration + 1)
// once given number of seconds passed -- navigate back
finalize(()=>{
this.goBack(true);
})
// just in case if user navigates out before condition is met
// this is needed if you wont use |async pipe
takeUntil(this.destroy$)
// map to display time
map(value => this.dhms(duration - value))
);
}
然后将| async
管道应用于模板中的message$
。
希望这会有所帮助