取消订阅后 Rxjs 计时器重新启动
Rxjs timer restarts after unsubscribe
我开始制作一个简单的游戏来测试反应能力。当红色矩形变为绿色时,玩家必须点击图形并显示结果。问题是点击矩形后计时器开始 again.I 使用取消订阅,但没有结果。
示例:https://stackblitz.com/edit/angular-ivy-w8uejd?file=src%2Fapp%2Fapp.component.ts
代码:
HTML
<div (click)="onRegtangleClicked()" class="rectangle" id="rectangle"></div>
<div class="button">
<button (click)="onStartClicked()" class="btn btn-success">Start</button>
</div>
<p class="text">You score is: {{time}} (lower is better)</p>
SCSS
.rectangle {
position: relative;
height: 500px;
width: 100%;
background-color: rgb(255, 0, 0);
cursor: pointer;
}
.button{
margin-left: 40%;
margin-top: 2%;
position: relative;
}
.text{
font-size: large;
position: relative;
margin-left: 40%;
}
打字稿
import { Component, OnInit } from '@angular/core';
import { timer } from 'rxjs';
@Component({
selector: 'app-reflexgame',
templateUrl: './reflexgame.component.html',
styleUrls: ['./reflexgame.component.scss'],
})
export class ReflexgameComponent implements OnInit {
time: number = 0;
subscription: any;
constructor() {}
ngOnInit(): void {}
onStartClicked() {
let randomNumber:number = Math.random() * 5;
setInterval(() => {
document.getElementById('rectangle')!.style.backgroundColor = 'green';
this.observableTimer();
}, randomNumber * 1000);
}
onRegtangleClicked() {
this.subscription.unsubscribe();
}
observableTimer() {
this.subscription = timer(0, 1).subscribe((val) => {
this.time = val;
});
}
}
我不知道我哪里错了?
您的代码中断的原因是因为
- 您甚至在创建订阅之前就调用了
unsubscribe()
:要修复此问题,您可以添加一个标志以便了解订阅是否处于活动状态。
- 创建间隔时最好清除间隔。
两种逻辑都适合我,试一试
计时器一次又一次地重新启动,因为在方法 onStartClicked()
中您正在使用 setInterval
。您在间隔内定义的逻辑每 x 秒连续执行一次,直到您调用 clearInterval(theIntervalToClear)
.
在您的情况下,您应该使用 setTimeout
仅在 x 秒后触发一次逻辑。
干杯
我开始制作一个简单的游戏来测试反应能力。当红色矩形变为绿色时,玩家必须点击图形并显示结果。问题是点击矩形后计时器开始 again.I 使用取消订阅,但没有结果。
示例:https://stackblitz.com/edit/angular-ivy-w8uejd?file=src%2Fapp%2Fapp.component.ts
代码:
HTML
<div (click)="onRegtangleClicked()" class="rectangle" id="rectangle"></div>
<div class="button">
<button (click)="onStartClicked()" class="btn btn-success">Start</button>
</div>
<p class="text">You score is: {{time}} (lower is better)</p>
SCSS
.rectangle {
position: relative;
height: 500px;
width: 100%;
background-color: rgb(255, 0, 0);
cursor: pointer;
}
.button{
margin-left: 40%;
margin-top: 2%;
position: relative;
}
.text{
font-size: large;
position: relative;
margin-left: 40%;
}
打字稿
import { Component, OnInit } from '@angular/core';
import { timer } from 'rxjs';
@Component({
selector: 'app-reflexgame',
templateUrl: './reflexgame.component.html',
styleUrls: ['./reflexgame.component.scss'],
})
export class ReflexgameComponent implements OnInit {
time: number = 0;
subscription: any;
constructor() {}
ngOnInit(): void {}
onStartClicked() {
let randomNumber:number = Math.random() * 5;
setInterval(() => {
document.getElementById('rectangle')!.style.backgroundColor = 'green';
this.observableTimer();
}, randomNumber * 1000);
}
onRegtangleClicked() {
this.subscription.unsubscribe();
}
observableTimer() {
this.subscription = timer(0, 1).subscribe((val) => {
this.time = val;
});
}
}
我不知道我哪里错了?
您的代码中断的原因是因为
- 您甚至在创建订阅之前就调用了
unsubscribe()
:要修复此问题,您可以添加一个标志以便了解订阅是否处于活动状态。 - 创建间隔时最好清除间隔。
两种逻辑都适合我,试一试
计时器一次又一次地重新启动,因为在方法 onStartClicked()
中您正在使用 setInterval
。您在间隔内定义的逻辑每 x 秒连续执行一次,直到您调用 clearInterval(theIntervalToClear)
.
在您的情况下,您应该使用 setTimeout
仅在 x 秒后触发一次逻辑。
干杯