角度破坏计时器在服务中

时间:2017-05-12 15:15:47

标签: angular timer

我有一个带定时器的服务。由于服务没有生命周期挂钩,如何销毁计时器?

这是完整的项目: https://github.com/GregFinzer/AmbientStateExample

这是服务代码。注意ngOnDestroy(它永远不会被调用)。

// 3rd party imports
import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { Observable, Subscription } from 'rxjs/Rx';
import { AsyncLocalStorage } from 'angular-async-local-storage';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/do';
import {OnInit, OnDestroy} from '@angular/core';

// Our imports
import { Stock } from './stock-model';

@Injectable()
export class StockService  {
  private _url = 'http://finance.google.com/finance/info?client=ig&q=NASDAQ%3AAAPL,GOOG';
  private _timer;
  private _sub: Subscription;
  private _objectKey = 'stocksObject';
  private _dateKey = 'lastStockCheckDate';
  private _timerInterval = 60000; // Get data from the service every 60 seconds
  public lastChangeDate: Date;

  constructor(private _http: Http, protected _storage: AsyncLocalStorage) {
    this._timer = Observable.timer(0, this._timerInterval);
    this._sub = this._timer.subscribe(tick => { this.timerTick(tick); });
  }

  // This will not be hit, not sure how to implement in a service
    ngOnDestroy() {
        console.log('Destroy timer');
        this._sub.unsubscribe();
    }

  timerTick(tick) {
      console.log('Interval hit: ' + tick);
      this.processCache();
  }

  // Get the stocks from the local storage cache
  public getFromCache(): Observable<Stock[]> {
    console.error('getStockCache()');
    return this._storage.getItem(this._objectKey);
  }



  private processCache(): void {
    console.log('processCache()');
    this._storage.getItem(this._dateKey).subscribe((lastCheckDate) => {
        let now = new Date();

        if (lastCheckDate) {
          // Default last change date to the last check date
          if (!this.lastChangeDate) {
            this.lastChangeDate = lastCheckDate;
          }

          // Obey the timer interval even if the user restarts the application
          if ((now.getTime() - lastCheckDate.getTime()) < this._timerInterval) {
            return;
          }
        }

        // Save the last check date
        this.updateLastCheckDate();

        // Get the data from the service
        let servicePromise: Promise<Stock[]> = this.getDataFromService().toPromise();

        // If anything changed, save to local storage
        servicePromise.then((serviceData) => {
          this._storage.getItem(this._objectKey).subscribe((storageData) => {
            if (this.anythingChanged(serviceData, storageData)) {
                this._storage.setItem(this._objectKey, serviceData)
                  .subscribe(() => { this.lastChangeDate = new Date(); }, () => {});
            }
          }, () => {});
        });
      }, () => {});
  }

  // Has anything changed from what was returned from the service vs what we have in local storage?
  private anythingChanged(serviceData: Stock[], storageData: Stock[]): boolean  {
    console.log('anythingChanged()');

    if (!storageData) {
      return true;
    }

    if (serviceData.length !== storageData.length) {
      return true;
    }

    for (let i = 0; i < serviceData.length; i++) {
      if (serviceData[i].l_cur !== storageData[i].l_cur) {
        return true;
      }
    }

    return false;
  }


  // Update the last time we called the service
  private updateLastCheckDate(): void  {
    console.error('updateLastCheckDate()');
    const now = new Date();
    this._storage.setItem(this._dateKey, now).subscribe(() => {}, () => {});
  }



  // Get stocks from the service
  private getDataFromService(): Observable<Stock[]> {
    console.error('getStocks()');
    return this._http.get(this._url, this.getRequestOptions())
    .do((data: Response) => console.log('All: ' +  data.text()))
    // The substr is required because Google puts in two comment characters //
    .map((response: Response) => <Stock[]> JSON.parse(response.text().substr(3)));
  }

  // Write any errors out to the console
  private handleError(error: Response) {
    console.error(error);
    let msg = `Error status code ${error.status} at ${error.url}`;
    return Observable.throw(msg);
  }

  // Ensure we get JSON from the service
  private getRequestOptions(): RequestOptions {
    let opt: RequestOptions;
    let myHeaders: Headers = new Headers;

    myHeaders.append('Accept', 'application/json');

    opt = new RequestOptions();
    opt.headers = myHeaders;

    return opt;
  }
}

0 个答案:

没有答案