#angular #timer #rxjs #unsubscribe
#angular #таймер #rxjs #отменить подписку
Вопрос:
Я начал создавать простую игру для проверки рефлексов. Когда красный прямоугольник станет зеленым, игрок должен нажать на фигуру, и отобразится результат. Проблема в том, что после нажатия на прямоугольник таймер запускается снова.Я использую unsubscribe для этого, но никаких результатов.
Пример: https://stackblitz.com/edit/angular-ivy-w8uejd?file=src/app/app.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%;
}
typescript
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;
});
}
}
Я не знаю, где я ошибаюсь?
Комментарии:
1. Итак, вы хотите остановиться после нажатия прямоугольника?
2. Да, а затем результат будет отображаться на экране
3. Можете ли вы попробовать это?
this.subscription.complete();
внутри вашегоonRegtangleClicked()
Ответ №1:
Таймер перезапускается снова и снова, потому что в onStartClicked()
используемом вами методе setInterval
. Логика, которую вы определяете внутри интервала, выполняется непрерывно каждые x секунд, пока вы не вызовете clearInterval(theIntervalToClear)
.
В вашем случае вы должны использовать a setTimeout
, чтобы запускать логику только один раз после прохождения x секунд.
приветствия
Комментарии:
1. Да! Я глуп. Спасибо!
Ответ №2:
Причина вашего разрыва кода заключается в том, что
- Вы вызываете
unsubscribe()
еще до создания подписки: чтобы исправить это, вы можете добавить флаг, чтобы узнать, активна подписка или нет. - При создании интервала лучше очистить интервал.
У меня это работает с обеими логиками, попробуйте