Cara membuat timer di angular2

95

Saya membutuhkan pengatur waktu di Angular 2, yang berdetak setelah interval waktu dan melakukan beberapa tugas (mungkin memanggil beberapa fungsi).

Bagaimana melakukan ini dengan Angular 2?

kuntal
sumber
2
Sertakan kode secukupnya untuk memungkinkan orang lain mereproduksi masalah. Untuk bantuan dalam hal ini, baca Cara membuat contoh Minimal, Lengkap, dan Dapat Diverifikasi. Jika memungkinkan untuk membuat contoh langsung dari masalah yang dapat Anda tautkan (misalnya, di sqlfiddle.com atau jsbin.com ), lakukanlah - tetapi juga sertakan kode dalam pertanyaan Anda itu sendiri. Tidak semua orang dapat mengakses situs eksternal, dan tautan dapat rusak seiring waktu.
Prasad
15
Ini sebenarnya pertanyaan yang sangat membantu. Observable penting untuk dipelajari dan digunakan. Meskipun pengguna tidak memiliki kode untuk pergi dari pertanyaan ini akan membantu orang lain.
Winnemucca
Komentar ini termasuk dalam keranjang yang sama, tetapi tidak satu pun dari 2 orang sebelumnya yang membantu, hanya mengomentari pertanyaan ... Tampaknya sekarang orang-orang menggunakan setTimeout lagi.
rbnzdave
setTimeout benar-benar jadul - periksa TimerObservable baru di bawah
Philip
2
biarkan this._timer = setInterval (() => this.getWidgetData (), 10000); dan pastikan untuk memanggil clearInterval (this._timer); di hancurkan
crh225

Jawaban:

129

Selain semua jawaban sebelumnya, saya akan melakukannya dengan menggunakan RxJS Observables

silakan periksa Observable.timer

Berikut ini contoh kode, akan dimulai setelah 2 detik dan kemudian berdetak setiap detik:

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

Dan ini alat pemecah yang berfungsi

Memperbarui Jika Anda ingin memanggil fungsi yang dideklarasikan di kelas AppComponent, Anda dapat melakukan salah satu hal berikut:

** Dengan asumsi fungsi yang ingin Anda panggil bernama func ,

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

Masalah dengan pendekatan di atas adalah jika Anda memanggil 'ini' di dalam func, ini akan merujuk ke objek pelanggan alih-alih objek AppComponent yang mungkin bukan yang Anda inginkan.

Namun, dalam pendekatan di bawah ini, Anda membuat ekspresi lambda dan memanggil fungsi func di dalamnya. Dengan cara ini, panggilan ke func masih berada di dalam cakupan AppComponent. Ini adalah cara terbaik untuk melakukannya menurut saya.

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

periksa plunker ini untuk kode kerja.

Abdulrahman Alsoghayer
sumber
Haruskah saya bisa meneruskan fungsi ke `timer.subscribe (t => this.ticks = t);` yang dipanggil di setiap centang?
kuntal
@matrixwebtech Ya, 't => this.ticks = t' adalah ekspresi lambda, persis sama dengan 'function (t) {this.ticks = t}'
Abdulrahman Alsoghayer
Saya mencoba timer.subscribe (nama fungsi () {console.log ("hhhhhh")}); yang berfungsi tetapi bagaimana saya memanggil fungsi yang dideklarasikan secara terpisah ngOnInit () {let timer = Observable.timer (2000,1000); timer.subscribe (function () {this.fun ();}); } fun () {console.log ("hhhhhh")}
kuntal
@matrixwebtech silakan periksa jawaban saya yang diperbarui untuk contoh.
Abdulrahman Alsoghayer
1
@Notflip Di bawah tenda, timertampaknya digunakan setInterval(). Namun, Anda dapat meneruskan animationFramepenjadwal (yang menggunakan requestAnimationFrame()) untuk menggunakannya alih-alih asyncpenjadwal default . Yang perlu Anda lakukan adalah Observable.timer(*,*,Scheduler.animationFrame), diberikan import {Scheduler} from ‘rxjs’. Meskipun, timertampaknya tidak berhasil. Sepertinya masih digunakan setInterVal(). Namun, pada observasi jenis lain seperti Observable.range(0,1000,Scheduler.animationFrame), requestAnimationFramedigunakan secara pasti. kinerja bijaksana, saya tidak bisa menjawab Anda dengan pasti sekarang.
Abdulrahman Alsoghayer
79

Solusi lain adalah dengan menggunakan TimerObservable

TimerObservable adalah subclass dari 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: Jangan lupa berhenti berlangganan.

Philip
sumber
3
bagian berhenti berlangganan adalah kuncinya
Tucker
bagaimana Anda berhenti berlangganan? dan kapan?
Miguel Stevens
1
@Notflip ngOnDestroy dipanggil selama deinitialization komponen: this.subscription.unsubscribe();berhenti berlangganan.
Philip
Bagaimana Anda dapat menggunakan this.subscription tanpa mereferensikannya di atas?
Winnemucca
2
Bagaimana Anda menjeda dan memulai ulang?
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
sumber
3
Ini tidak menambahkan apa pun yang belum dijelaskan dalam jawaban lain, atau bukan?
Günter Zöchbauer
5

Dengan rxjs 6.2.2 dan Angular 6.1.7, saya mendapatkan:

Observable.timer is not a function

kesalahan. Ini diselesaikan dengan mengganti Observable.timerdengan 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
sumber
3
Untuk berhenti berlangganan, Anda harus memiliki variabel langganan seperti @ alexis-poo di atas. Lihat: stackoverflow.com/questions/40181169/… . Saya mendasarkan ini pada jawaban Anda yang tidak berfungsi seperti yang tertulis dalam hal itu.
Reid
Saya suka orang ini yang selalu memperbarui Postingan ke versi Angular terbaru ... Setiap kali begitu banyak kesulitan dengan AngularJS dan Angular. Terima kasih sobat!
tangga rantai
4

Anda cukup menggunakan utilitas setInterval dan menggunakan fungsi panah sebagai callback sehingga thisakan mengarah ke instance komponen.

Misalnya:

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

Di dalam hook siklus hidup ngOnDestroy Anda, kosongkan intervalnya.

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

Saya menghadapi masalah karena saya harus menggunakan pengatur waktu, tetapi saya harus menampilkannya dalam 2 komponen waktu yang sama, layar yang sama. Saya membuat timerObservable dalam sebuah layanan. Saya berlangganan pengatur waktu di kedua komponen, dan apa yang terjadi? Itu tidak akan disinkronkan, karena langganan baru selalu membuat alirannya sendiri.

Apa yang ingin saya katakan, adalah bahwa jika Anda berencana untuk menggunakan satu .publishReplay(1).refCount() pengatur waktu di beberapa tempat, selalu diletakkan di ujung Pengamat, karena itu akan menerbitkan aliran yang sama setiap saat.

Contoh:

this.startDateTimer = Observable.combineLatest(this.timer, this.startDate$, (localTimer, startDate) => {
  return this.calculateTime(startDate);
}).publishReplay(1).refCount();
xyztdanid4
sumber
dapatkah Anda berbagi implementasi?
Nitish Kumar
1

Menemukan paket npm yang mempermudah ini dengan RxJS sebagai layanan.

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

Anda dapat 'berlangganan' ke pengatur waktu yang ada sehingga Anda tidak membuat banyak penghitung waktu jika Anda menggunakannya berkali-kali dalam komponen yang sama.

Simon_Weaver
sumber
1

Jika Anda ingin menjalankan metode di ngOnInit, Anda dapat melakukan sesuatu seperti ini:

impor 2 pustaka ini dari RXJS:

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

Kemudian nyatakan timer dan private subscription, contoh:

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

Terakhir, jalankan metode saat timer berhenti

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

Itu saja, Angular 5

Alexis Poo
sumber
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
sumber