Cómo crear un temporizador en angular2


95

Necesito un temporizador en Angular 2, que marca después de un intervalo de tiempo y realiza alguna tarea (puede ser llamar a algunas funciones).

¿Cómo hacer esto con Angular 2?


2
Incluya solo el código suficiente para permitir que otros reproduzcan el problema. Para obtener ayuda con esto, lea Cómo crear un ejemplo mínimo, completo y verificable. Si es posible crear un ejemplo en vivo del problema al que puede vincular (por ejemplo, en sqlfiddle.com o jsbin.com ), hágalo, pero también incluya el código en su pregunta. No todo el mundo puede acceder a sitios externos y los enlaces pueden romperse con el tiempo.
Prasad

15
En realidad, esta es una pregunta muy útil. Los observables son importantes para aprender y usar. Incluso si el usuario no tiene un código para partir de esta pregunta, será útil para otros.
Winnemucca

Este comentario cae en el mismo cubo, pero ninguna de las 2 personas anteriores ha ayudado, solo comentó la pregunta ... Aparentemente, la gente está usando setTimeout nuevamente ahora.
rbnzdave

setTimeout es realmente de la vieja escuela - echa un vistazo al nuevo TimerObservable a continuación
Philip

2
let this._timer = setInterval (() => this.getWidgetData (), 10000); y asegúrese de llamar a clearInterval (this._timer); al destruir
crh225

Respuestas:


129

Además de todas las respuestas anteriores, lo haría usando RxJS Observables

por favor revise Observable.timer

Aquí hay un código de muestra, comenzará después de 2 segundos y luego marcará cada segundo:

import {Component} from 'angular2/core';
import {Observable} from 'rxjs/Rx';

@Component({
    selector: 'my-app',
    template: 'Ticks (every second) : {{ticks}}'
})
export class AppComponent {
  ticks =0;
  ngOnInit(){
    let timer = Observable.timer(2000,1000);
    timer.subscribe(t=>this.ticks = t);
  }
}

Y aquí hay un plunker que funciona

Actualizar Si desea llamar a una función declarada en la clase AppComponent, puede realizar una de las siguientes acciones:

** Suponiendo que la función que desea llamar se llama func ,

ngOnInit(){
    let timer = Observable.timer(2000,1000);
    timer.subscribe(this.func);
}

El problema con el enfoque anterior es que si llama a 'esto' dentro de la función, se referirá al objeto del suscriptor en lugar del objeto AppComponent, que probablemente no sea lo que desea.

Sin embargo, en el siguiente enfoque, crea una expresión lambda y llama a la función func dentro de ella. De esta manera, la llamada a func todavía está dentro del alcance de AppComponent. Esta es la mejor forma de hacerlo en mi opinión.

ngOnInit(){
    let timer = Observable.timer(2000,1000);
    timer.subscribe(t=> {
        this.func(t);
    });
}

revise este plunker para ver el código de trabajo.


¿Debería poder pasar una función a `timer.subscribe (t => this.ticks = t);` que es una llamada en cada tick?
kuntal

@matrixwebtech Sí, 't => this.ticks = t' es una expresión lambda, exactamente lo mismo que 'function (t) {this.ticks = t}'
Abdulrahman Alsoghayer

Intento timer.subscribe (function name () {console.log ("hhhhhh")}); cuál funciona pero cómo llamo a una función que declaró por separado ngOnInit () {let timer = Observable.timer (2000,1000); timer.subscribe (function () {this.fun ();}); } fun () {console.log ("hhhhhh")}
kuntal

@matrixwebtech, consulte mi respuesta actualizada para ver ejemplos.
Abdulrahman Alsoghayer

1
@Notflip Debajo del capó, timerparece usar setInterval(). Pero, puede pasar el animationFrameprogramador (que usa requestAnimationFrame()) para usarlo en lugar del asyncprogramador predeterminado . Todo lo que necesita hacer es Observable.timer(*,*,Scheduler.animationFrame), dado. import {Scheduler} from ‘rxjs’Aunque, timerno parece funcionar. Todavía parece usar setInterVal(). Sin embargo, en otros tipos de observables como Observable.range(0,1000,Scheduler.animationFrame), el requestAnimationFramese usa con seguridad. En cuanto al rendimiento, no puedo responderte con seguridad en este momento.
Abdulrahman Alsoghayer

79

Otra solución es utilizar TimerObservable

TimerObservable es una subclase de Observable.

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Subscription} from "rxjs";
import {TimerObservable} from "rxjs/observable/TimerObservable";

@Component({
  selector: 'app-component',
  template: '{{tick}}',
})
export class Component implements OnInit, OnDestroy {

  private tick: string;
  private subscription: Subscription;

  constructor() {
  }

  ngOnInit() {
    let timer = TimerObservable.create(2000, 1000);
    this.subscription = timer.subscribe(t => {
      this.tick = t;
    });
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

PD: No te olvides de darte de baja.


3
la parte para cancelar la suscripción es clave
Tucker

¿cómo se da de baja? ¿y cuando?
Miguel Stevens

1
Se llama a @Notflip ngOnDestroy durante la desinicialización del componente: cancela la this.subscription.unsubscribe();suscripción.
Philip

¿Cómo puede utilizar this.subscription sin hacer referencia a ella arriba?
Winnemucca

2
¿Cómo pausarlo y reiniciarlo?
Dani

11
import {Component, View, OnInit, OnDestroy} from "angular2/core";

import { Observable, Subscription } from 'rxjs/Rx';

@Component({

})
export class NewContactComponent implements OnInit, OnDestroy {

    ticks = 0;
    private timer;
    // Subscription object
    private sub: Subscription;


    ngOnInit() {
        this.timer = Observable.timer(2000,5000);
        // subscribing to a observable returns a subscription object
        this.sub = this.timer.subscribe(t => this.tickerFunc(t));
    }
    tickerFunc(tick){
        console.log(this);
        this.ticks = tick
    }

    ngOnDestroy(){
        console.log("Destroy timer");
        // unsubscribe here
        this.sub.unsubscribe();

    }


}

3
Esto no agrega nada que no se haya explicado en otras respuestas, ¿o sí?
Günter Zöchbauer

5

Con rxjs 6.2.2 y Angular 6.1.7, obtenía un:

Observable.timer is not a function

error. Esto se resolvió reemplazando Observable.timercon timer:

import { timer, Subscription } from 'rxjs';

private myTimerSub: Subscription;    

ngOnInit(){    
    const ti = timer(2000,1000);    
    this.myTimerSub = ti.subscribe(t => {    
        console.log("Tick");    
    });    
}    

ngOnDestroy() {    
    this.myTimerSub.unsubscribe();    
}

3
Para cancelar la suscripción, debe tener una variable de suscripción como @ alexis-poo arriba. Ver: stackoverflow.com/questions/40181169/… . Baso esto en que su respuesta no funciona como está escrita en ese sentido.
Reid

Amo a este tipo que siempre está actualizando las publicaciones a las versiones más nuevas de Angular ... Cada vez hay tanta lucha con AngularJS y Angular. ¡Gracias hombre!
escalera

4

Simplemente puede usar la utilidad setInterval y usar la función de flecha como devolución de llamada para que thisapunte a la instancia del componente.

Por ejemplo:

this.interval = setInterval( () => { 
    // call your functions like 
    this.getList();
    this.updateInfo();
});

Dentro de su gancho de ciclo de vida ngOnDestroy, borre el intervalo.

ngOnDestroy(){
    clearInterval(this.interval);
}

3

Me enfrenté al problema de que tenía que usar un temporizador, pero tenía que mostrarlos en 2 componentes al mismo tiempo, la misma pantalla. Creé el timerObservable en un servicio. Me suscribí al temporizador en ambos componentes y ¿qué sucedió? No se sincronizará, porque la nueva suscripción siempre crea su propia transmisión.

Lo que me gustaría decir es que si planeas usar un temporizador en varios lugares, colócalo siempre .publishReplay(1).refCount() al final del Observador, porque publicará la misma secuencia cada vez.

Ejemplo:

this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
  return this.calculateTime(startDate);
}).publishReplay(1).refCount();

¿Puedes compartir tu implementación?
Nitish Kumar


1

Si busca ejecutar un método en ngOnInit, podría hacer algo como esto:

importar estas 2 bibliotecas de RXJS:

import {Observable} from 'rxjs/Rx';
import {Subscription} from "rxjs";

Luego declare el temporizador y la suscripción privada, ejemplo:

timer= Observable.timer(1000,1000); // 1 second for 2 seconds (2000,1000) etc
private subscription: Subscription;

Por último, pero no menos importante, ejecutar el método cuando el temporizador se detiene

ngOnInit() {
  this.subscription = this.timer.subscribe(ticks=> {
    this.populatecombobox();  //example calling a method that populates a combobox
    this.subscription.unsubscribe();  //you need to unsubscribe or it will run infinite times
  });
}

Eso es todo, Angular 5


0
Set Timer and auto call service after certain time
// Initialize from ngInit
ngOnInit(): void {this.getNotifications();}

getNotifications() {
    setInterval(() => {this.getNewNotifications();
    }, 60000);  // 60000 milliseconds interval 
}
getNewNotifications() {
    this.notifyService.getNewNotifications().subscribe(
        data => { // call back },
        error => { },
    );
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.