Come creare un timer in angular2


95

Ho bisogno di un timer in Angular 2, che ticchetta dopo un intervallo di tempo e svolga un compito (potrebbe essere chiamato alcune funzioni).

Come farlo con Angular 2?


2
Includere appena il codice sufficiente per consentire ad altri di riprodurre il problema. Per assistenza in merito, leggi Come creare un esempio minimo, completo e verificabile. Se è possibile creare un esempio dal vivo del problema a cui è possibile collegarsi (ad esempio, su sqlfiddle.com o jsbin.com ), farlo, ma includere anche il codice nella domanda stessa. Non tutti possono accedere a siti esterni e i collegamenti potrebbero interrompersi nel tempo.
Prasad

15
Questa è in realtà una domanda molto utile. Gli osservabili sono importanti da apprendere e utilizzare. Anche se l'utente non aveva il codice per passare da questa domanda sarà utile agli altri.
Winnemucca

Questo commento rientra nello stesso secchio, ma nessuna delle 2 persone precedenti ha aiutato, ha appena commentato la domanda ... Apparentemente le persone stanno usando di nuovo setTimeout ora.
rbnzdave

setTimeout è davvero vecchia scuola - controlla il nuovo TimerOsservabile di seguito
Philip

2
lascia che this._timer = setInterval (() => this.getWidgetData (), 10000); e assicurati di chiamare clearInterval (this._timer); sulla distruzione
crh225

Risposte:


129

Oltre a tutte le risposte precedenti, lo farei usando RxJS Observables

si prega di controllare Observable.timer

Ecco un codice di esempio, inizierà dopo 2 secondi e poi scatta ogni secondo:

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);
  }
}

Ed ecco un plunker funzionante

Aggiorna Se vuoi chiamare una funzione dichiarata nella classe AppComponent, puoi eseguire una delle seguenti operazioni:

** Supponendo che la funzione che vuoi chiamare sia chiamata func ,

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

Il problema con l'approccio precedente è che se chiami "this" all'interno di func, si farà riferimento all'oggetto del sottoscrittore invece che all'oggetto AppComponent che probabilmente non è quello che desideri.

Tuttavia, nell'approccio seguente, crei un'espressione lambda e chiami la funzione func al suo interno. In questo modo, la chiamata a func è ancora all'interno dell'ambito di AppComponent. Questo è il modo migliore per farlo secondo me.

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

controlla questo plunker per il codice funzionante.


Devo essere in grado di passare una funzione a `timer.subscribe (t => this.ticks = t);` che è chiamata in ogni tick?
kuntal

@matrixwebtech Sì, "t => this.ticks = t" è un'espressione lambda, esattamente uguale a "function (t) {this.ticks = t}"
Abdulrahman Alsoghayer

Provo timer.subscribe (nome funzione () {console.log ("hhhhhh")}); che funziona ma come chiamo una funzione che ha dichiarato separatamente ngOnInit () {let timer = Observable.timer (2000,1000); timer.subscribe (function () {this.fun ();}); } fun () {console.log ("hhhhhh")}
kuntal

@ matrixwebtech per favore controlla la mia risposta aggiornata per esempi.
Abdulrahman Alsoghayer

1
@Notflip Under the hood, timersembra usare setInterval(). Ma puoi passare lo animationFramescheduler (che usa requestAnimationFrame()) per usarlo al posto dello asyncscheduler predefinito . Tutto quello che devi fare è Observable.timer(*,*,Scheduler.animationFrame), dato import {Scheduler} from ‘rxjs’, anche timerse sembra che non funzioni. Sembra ancora da usare setInterVal(). Tuttavia, su altri tipi di osservabili come Observable.range(0,1000,Scheduler.animationFrame), requestAnimationFrameviene sicuramente utilizzato. dal punto di vista delle prestazioni, non posso risponderti di sicuro in questo momento.
Abdulrahman Alsoghayer

79

Un'altra soluzione è usare TimerObservable

TimerObservable è una sottoclasse di 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();
  }
}

PS: non dimenticare di annullare l'iscrizione.


3
la parte di annullamento dell'iscrizione è la chiave
Tucker

come si annulla l'iscrizione? e quando?
Miguel Stevens

1
@Notflip ngOnDestroy viene chiamato durante la deinizializzazione dei componenti: annulla l' this.subscription.unsubscribe();iscrizione.
Philip,

Come puoi usare this.subscription senza farvi riferimento sopra?
Winnemucca

2
Come lo metti in pausa e lo riavvii?
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
Questo non aggiunge nulla che non sia già spiegato in altre risposte, o lo fa?
Günter Zöchbauer

5

Con rxjs 6.2.2 e Angular 6.1.7, stavo ottenendo un:

Observable.timer is not a function

errore. Questo è stato risolto sostituendo 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
Per annullare l'iscrizione, devi avere una variabile di iscrizione come @ alexis-poo sopra. Vedi: stackoverflow.com/questions/40181169/… . Baso questo sulla tua risposta che non funziona come scritto al riguardo.
Reid

Adoro questo ragazzo che aggiorna sempre i post alle versioni Angular più recenti ... Ogni volta che lotta con AngularJS e Angular. Grazie uomo!
Catene del

4

Puoi semplicemente usare l'utility setInterval e usare la funzione freccia come callback in modo che thispunti all'istanza del componente.

Ad esempio:

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

All'interno del tuo hook del ciclo di vita ngOnDestroy, cancella l'intervallo.

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

3

Ho riscontrato un problema che ho dovuto utilizzare un timer, ma ho dovuto visualizzarli in 2 componenti contemporaneamente, sullo stesso schermo. Ho creato il timerObservable in un servizio. Mi sono iscritto al timer in entrambi i componenti e cosa è successo? Non verrà sincronizzato, perché il nuovo abbonamento crea sempre il proprio flusso.

Quello che vorrei dire è che se prevedi di usare un timer in più punti, mettilo sempre .publishReplay(1).refCount() alla fine dell'Observer, perché pubblicherà lo stesso flusso ogni volta.

Esempio:

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

puoi condividere la tua implementazione?
Nitish Kumar


1

Se cerchi di eseguire un metodo su ngOnInit potresti fare qualcosa del genere:

importa queste 2 librerie da RXJS:

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

Quindi dichiara timer e abbonamento privato, esempio:

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

Ultimo ma non meno importante metodo di esecuzione quando il timer si ferma

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
  });
}

Questo è tutto, 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 => { },
    );
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.