So erstellen Sie einen Timer in angle2

95

Ich brauche einen Timer in Angular 2, der nach einem Zeitintervall tickt und eine Aufgabe erledigt (kann einige Funktionen aufrufen).

Wie geht das mit Angular 2?

kuntal
quelle
2
Fügen Sie gerade genug Code ein, damit andere das Problem reproduzieren können. Weitere Informationen hierzu finden Sie unter Erstellen eines minimalen, vollständigen und überprüfbaren Beispiels. Wenn es möglich ist, ein Live-Beispiel für das Problem zu erstellen, auf das Sie verlinken können (z. B. auf sqlfiddle.com oder jsbin.com ), tun Sie dies - aber fügen Sie den Code auch in Ihre Frage selbst ein. Nicht jeder kann auf externe Websites zugreifen, und die Links können im Laufe der Zeit unterbrochen werden.
Prasad
15
Dies ist eigentlich eine sehr hilfreiche Frage. Observables sind wichtig zu lernen und zu verwenden. Auch wenn der Benutzer keinen Code für diese Frage hatte, ist dies für andere hilfreich.
Winnemucca
Dieser Kommentar fällt in den gleichen Bereich, aber keine der beiden vorherigen Personen hat geholfen, sondern nur die Frage kommentiert ... Anscheinend verwenden die Benutzer setTimeout jetzt wieder.
Rbnzdave
setTimeout ist wirklich altmodisch - sehen Sie sich das frische TimerObservable unten an
Philip
2
let this._timer = setInterval (() => this.getWidgetData (), 10000); und stellen Sie sicher, dass Sie clearInterval (this._timer) aufrufen. auf zerstören
crh225

Antworten:

129

Zusätzlich zu allen vorherigen Antworten würde ich RxJS Observables verwenden

Bitte überprüfen Sie Observable.timer

Hier ist ein Beispielcode, der nach 2 Sekunden startet und dann jede Sekunde ankreuzt:

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

Und hier ist ein funktionierender Plunker

Aktualisieren Wenn Sie eine in der AppComponent-Klasse deklarierte Funktion aufrufen möchten, haben Sie folgende Möglichkeiten:

** Angenommen, die Funktion, die Sie aufrufen möchten, heißt func .

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

Das Problem mit dem obigen Ansatz besteht darin, dass, wenn Sie 'this' in func aufrufen, es auf das Abonnentenobjekt anstatt auf das AppComponent-Objekt verweist, was wahrscheinlich nicht das ist, was Sie wollen.

Im folgenden Ansatz erstellen Sie jedoch einen Lambda-Ausdruck und rufen die darin enthaltene Funktion func auf . Auf diese Weise befindet sich der Aufruf von func immer noch im Bereich von AppComponent. Dies ist meiner Meinung nach der beste Weg, dies zu tun.

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

Überprüfen Sie diesen Plunker auf Arbeitscode .

Abdulrahman Alsoghayer
quelle
Sollte ich in der Lage sein, eine Funktion an `timer.subscribe (t => this.ticks = t);` zu übergeben, die in jedem Tick aufgerufen wird?
Kuntal
@matrixwebtech Ja, das 't => this.ticks = t' ist ein Lambda-Ausdruck, genau das gleiche wie 'function (t) {this.ticks = t}'
Abdulrahman Alsoghayer
Ich versuche timer.subscribe (Funktionsname () {console.log ("hhhhhh")}); welche funktioniert aber wie ich eine Funktion aufrufe, die ngOnInit () separat deklariert {let timer = Observable.timer (2000,1000); timer.subscribe (function () {this.fun ();}); } fun () {console.log ("hhhhhh")}
kuntal
@matrixwebtech Bitte überprüfen Sie meine aktualisierte Antwort für Beispiele.
Abdulrahman Alsoghayer
1
@Notflip Unter der Haube timerscheint zu verwenden setInterval(). Sie können jedoch den animationFrameScheduler (der verwendet requestAnimationFrame()) übergeben, um ihn anstelle des Standard- asyncSchedulers zu verwenden. Alles, was Sie tun müssen, ist Observable.timer(*,*,Scheduler.animationFrame)gegeben. import {Scheduler} from ‘rxjs’Allerdings timerscheint es nicht zu funktionieren. Es scheint immer noch zu verwenden setInterVal(). Bei anderen Arten von Beobachtungsobjekten wie Observable.range(0,1000,Scheduler.animationFrame)dem requestAnimationFramewird das jedoch mit Sicherheit verwendet. In Bezug auf die Leistung kann ich Ihnen derzeit nicht sicher antworten.
Abdulrahman Alsoghayer
79

Eine andere Lösung ist die Verwendung von TimerObservable

TimerObservable ist eine Unterklasse von 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: Vergiss nicht, dich abzumelden.

Philip
quelle
3
Der Teil zum Abbestellen ist der Schlüssel
Tucker
Wie melden Sie sich ab? und wann?
Miguel Stevens
1
@Notflip ngOnDestroy wird während der Deinitialisierung von Komponenten aufgerufen: this.subscription.unsubscribe();Abbestellen.
Philip
Wie können Sie this.subscription verwenden, ohne oben darauf zu verweisen?
Winnemucca
2
Wie können Sie es anhalten und neu starten?
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();

    }


}
Unnikrishnan Parameswaran
quelle
3
Dies fügt nichts hinzu, was nicht bereits in anderen Antworten erklärt wurde, oder?
Günter Zöchbauer
5

Mit rxjs 6.2.2 und Angular 6.1.7 bekam ich eine:

Observable.timer is not a function

Error. Dies wurde behoben, indem ersetzt wurde Observable.timerdurch 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();    
}
Matt Saunders
quelle
3
Um sich abzumelden, müssen Sie eine Abonnementvariable wie @ alexis-poo oben haben. Siehe: stackoverflow.com/questions/40181169/… . Ich stütze dies auf Ihre Antwort, die in dieser Hinsicht nicht so funktioniert, wie sie geschrieben wurde.
Reid
Ich liebe diesen Typen, der die Posts immer auf die neuesten Angular-Versionen aktualisiert ... Immer wenn er so viel mit AngularJS und Angular zu kämpfen hat. Danke, Mann!
Kettentreppe
4

Sie können einfach das Dienstprogramm setInterval verwenden und die Pfeilfunktion als Rückruf verwenden this auf die Komponenteninstanz wird.

Zum Beispiel:

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

Löschen Sie das Intervall in Ihrem ngOnDestroy-Lebenszyklus-Hook.

ngOnDestroy(){
    clearInterval(this.interval);
}
Shivang Gupta
quelle
3

Ich hatte das Problem, dass ich einen Timer verwenden musste, aber ich musste sie in zwei Komponenten gleichzeitig und auf demselben Bildschirm anzeigen. Ich habe das timerObservable in einem Dienst erstellt. Ich habe den Timer in beiden Komponenten abonniert, und was ist passiert? Es wird nicht synchronisiert, da ein neues Abonnement immer einen eigenen Stream erstellt.

Was ich sagen möchte, ist, dass, wenn Sie einen Timer an mehreren Stellen verwenden möchten, immer .publishReplay(1).refCount() am Ende des Observers stehen, da dieser jedes Mal den gleichen Stream daraus veröffentlicht.

Beispiel:

this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
  return this.calculateTime(startDate);
}).publishReplay(1).refCount();
xyztdanid4
quelle
Können Sie Ihre Implementierung teilen?
Nitish Kumar
1

Ich habe ein npm-Paket gefunden, das dies mit RxJS als Service einfach macht.

https://www.npmjs.com/package/ng2-simple-timer

Sie können einen vorhandenen Timer abonnieren, sodass Sie keine Unmengen von Timern erstellen, wenn Sie ihn mehrmals in derselben Komponente verwenden.

Simon_Weaver
quelle
1

Wenn Sie eine Methode für ngOnInit ausführen möchten, können Sie Folgendes tun:

Importieren Sie diese 2 Bibliotheken aus RXJS:

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

Dann deklarieren Sie Timer und privates Abonnement, Beispiel:

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

Last but not least Methode ausführen, wenn der Timer stoppt

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

Das ist alles, Angular 5

Alexis Poo
quelle
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 => { },
    );
}
Nazmul Nadim
quelle