es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El temporizador de RxJS se reinicia después de cancelar la suscripción.

Comencé a hacer un juego simple para probar los reflejos. Cuando el rectángulo rojo se pone verde, el jugador debe hacer clic en la figura y se muestra el resultado. El problema es que después de hacer clic en el rectángulo, el temporizador vuelve a empezar. Uso unsubscribe para esto, pero no obtengo resultados.

Ejemplo: https://stackblitz.com/edit/angular-ivy-w8uejd?file=src%2Fapp%2Fapp.component.ts

Código:

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">Tu puntaje es: {{time}} (menor es mejor)</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;
    });
  }
}

No sé en qué me equivoco.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Parece que el problema es que la función onRegtangleClicked() se está desuscribiendo de la suscripción al temporizador, pero esto no impide que el intervalo siga disparándose. Una posible solución es almacenar el ID del intervalo en una variable y luego limpiarlo cuando se haga clic en el rectángulo. Aquí tienes una implementación actualizada:

    HTML

    <div (click)="onRegtangleClicked()" class="rectangle" id="rectangle"></div>
    <div class="button">
        <button (click)="onStartClicked()" class="btn btn-success">Iniciar</button>
    </div>
    <p class="text">Tu puntaje es: {{time}} (menor es mejor)</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;
      intervalId: any;
    
      constructor() {}
    
      ngOnInit(): void {}
    
      onStartClicked() {
        let randomNumber: number = Math.random() * 5;
        this.intervalId = setInterval(() => {
          document.getElementById('rectangle')!.style.backgroundColor = 'green';
          this.observableTimer();
        }, randomNumber * 1000);
      }
    
      onRegtangleClicked() {
        clearInterval(this.intervalId);
        this.subscription.unsubscribe();
      }
    
      observableTimer() {
        this.subscription = timer(0, 1).subscribe((val) => {
          this.time = val;
        });
      }
    }
    

    En esta implementación actualizada, la variable intervalId se declara y se le asigna el valor de la llamada a setInterval() en onStartClicked(). Luego, en onRegtangleClicked(), se llama a la función clearInterval() con intervalId como argumento para detener el intervalo. Finalmente, se mantiene la llamada subscription.unsubscribe() para detener la suscripción al temporizador.

Comments are closed.