Таймер Rxjs перезапускается после отмены подписки

#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:

Причина вашего разрыва кода заключается в том, что

  1. Вы вызываете unsubscribe() еще до создания подписки: чтобы исправить это, вы можете добавить флаг, чтобы узнать, активна подписка или нет.
  2. При создании интервала лучше очистить интервал.

У меня это работает с обеими логиками, попробуйте