Як створити таймер в angular2


95

Мені потрібен таймер в Angular 2, який ставить галочку через певний проміжок часу і виконує якесь завдання (може викликати деякі функції).

Як це зробити за допомогою Angular 2?


2
Включіть достатньо коду, щоб інші могли відтворити проблему. Щоб отримати допомогу з цим, прочитайте Як створити мінімальний, повний та перевіряваний приклад. Якщо є можливість створити реальний приклад проблеми, на яку ви можете зробити посилання (наприклад, на sqlfiddle.com або jsbin.com ), зробіть це, - але також включіть код у своє запитання. Не кожен може отримати доступ до зовнішніх сайтів, і посилання можуть з часом порватися.
Прасад

15
Це насправді дуже корисне запитання. Спостережувані фактори важливі для вивчення та використання. Навіть якщо у користувача не було коду для переходу з цього питання, це буде корисно для інших.
Віннемукка

Цей коментар потрапляє в той самий відро, але жоден із попередніх двох людей не допоміг, просто прокоментував питання ... Очевидно, зараз люди знову використовують setTimeout.
rbnzdave

setTimeout - це справді олдскул - виїзд за свіжим таймером Спостережуваний нижче
Філіп

2
нехай this._timer = setInterval (() => this.getWidgetData (), 10000); і обов’язково зателефонуйте clearInterval (this._timer); на знищення
crh225

Відповіді:


129

На додаток до всіх попередніх відповідей, я б зробив це, використовуючи RxJS Observables

будь ласка, перевірте Observable.timer

Ось зразок коду, який почнеться через 2 секунди, а потім тикає щосекунди:

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

І ось робочий плунжер

Оновлення Якщо ви хочете викликати функцію, заявлену в класі AppComponent, ви можете зробити одне з наступного:

** Якщо припустити, що функція, яку ви хочете викликати, називається func ,

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

Проблема з наведеним вище підходом полягає в тому, що якщо ви викликаєте 'this' всередині func, він буде посилатися на об'єкт абонента замість об'єкта AppComponent, який, ймовірно, не те, що ви хочете.

Однак у наведеному нижче підході ви створюєте лямбда-вираз і викликаєте функцію func всередині нього. Таким чином, виклик func все ще знаходиться в межах AppComponent. На мій погляд, це найкращий спосіб зробити це.

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

перевірте цей плюнкер на наявність робочого коду.


Чи повинен я передавати функцію `timer.subscribe (t => this.ticks = t);` яка викликається у кожному галочці?
кунталь

@matrixwebtech Так, 't => this.ticks = t' - це лямбда-вираз, точно такий самий, як і 'function (t) {this.ticks = t}'
Абдулрахман Алсогейер, 06

Я намагаюся timer.subscribe (ім'я функції () {console.log ("hhhhhh")}); який працює, але як я називаю функцію, яка оголосила окремо ngOnInit () {let timer = Observable.timer (2000,1000); timer.subscribe (function () {this.fun ();}); } fun () {console.log ("hhhhhh")}
kuntal

@matrixwebtech, будь ласка, перевірте мою оновлену відповідь для прикладів.
Абдулрахман Алсогейер

1
@Notflip Під капотом, timerздається, використовується setInterval(). Але ви можете передати animationFrameпланувальник (який використовує requestAnimationFrame()), щоб використовувати його замість asyncпланувальника за замовчуванням . Все, що вам потрібно зробити, це Observable.timer(*,*,Scheduler.animationFrame)дано. import {Scheduler} from ‘rxjs’Хоча, timerздається , це не працює. Здається, це все ще використовується setInterVal(). Однак для інших видів спостережуваних, таких як Observable.range(0,1000,Scheduler.animationFrame), requestAnimationFrameвикористовується точно. з точки зору продуктивності, я не можу вам точно відповісти зараз.
Абдулрахман Алсогейер

79

Іншим рішенням є використання TimerObservable

TimerObservable - це підклас 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: Не забудьте скасувати підписку.


3
відмова від підписки є ключовою
Такер

як ви відписуєтесь? і коли?
Мігель Стівенс,

1
@Notflip ngOnDestroy викликається під час деініціалізації компонентів: скасовує this.subscription.unsubscribe();підписку.
Філіп

Як ви можете використовувати this.subscription без посилання на нього вище?
Віннемукка

2
Як зробити паузу та перезапустити?
Дані

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
Це не додає нічого, що вже не пояснено в інших відповідях, чи ні?
Гюнтер Цохбауер,

5

З rxjs 6.2.2 та Angular 6.1.7 я отримував:

Observable.timer is not a function

помилка. Це було вирішено заміною Observable.timerна 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
Щоб скасувати підписку, потрібно мати змінну передплати, як @ alexis-poo вище. Див .: stackoverflow.com/questions/40181169/… . Я базую це на тому, що ваша відповідь не працює, як написано в цьому відношенні.
Рейд

Мені подобається цей хлопець, який завжди оновлює повідомлення до найновіших версій Angular ... Щоразу стільки боротьби з AngularJS та Angular. Дякую людино!
ланцюговий схід

4

Ви можете просто використовувати утиліту setInterval і використовувати функцію стрілки як зворотний виклик this вказати на екземпляр компонента.

Наприклад:

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

Всередині гачка життєвого циклу ngOnDestroy очистіть інтервал.

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

3

Я зіткнувся з проблемою, що мені довелося використовувати таймер, але я повинен був відображати їх у 2-х компонентному часі, на одному екрані. Я створив timerObservable в службі. Я підписався на таймер обох компонентів, і що сталося? Він не буде синхронізований, оскільки нова передплата завжди створює власний потік.

Що я хотів би сказати, це те, що якщо ви плануєте використовувати один таймер у кількох місцях, завжди ставити його .publishReplay(1).refCount() в кінець Observer, оскільки він буде публікувати один і той самий потік з нього кожного разу.

Приклад:

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

Ви можете поділитися своїм впровадженням?
Нітіш Кумар,

1

Знайдено пакет npm, який полегшує це використання RxJS як послуги.

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

Ви можете "підписатись" на існуючий таймер, щоб не створювати мільйони таймерів, якщо ви використовуєте його багато разів в одному компоненті.


1

Якщо ви хочете запустити метод на ngOnInit, ви можете зробити щось подібне:

імпортувати ці 2 бібліотеки з RXJS:

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

Потім оголосіть таймер та приватну підписку, приклад:

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

Останній, але не менш важливий метод запуску, коли таймер зупиняється

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

Це все, 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 => { },
    );
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.