角度异步本地存储承诺解决了空

时间:2017-05-11 18:19:49

标签: angular

如何将Async Local Storage Observable转换为承诺并正确投射?

我正在尝试使用Angular Async Local Storage项目缓存一些服务数据: https://github.com/cyrilletuzi/angular-async-local-storage

数据正确保存到本地IndexDb(我在Chrome开发工具中查看过)。问题是我无法恢复数据。承诺解决了空洞。这是问题:

result => this._storage.getItem(this._objectKey).toPromise();

以下是完整来源的链接: https://github.com/GregFinzer/AmbientStateExample

以下是包含缓存的完整服务类:

// 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 _stocks: Promise<Stock[]>;
  private _timer;
  private _sub: Subscription;
  private _lastStockCheckDate: Date;
  private _objectKey = 'stocksObject';
  private _dateKey = 'lastStockCheckDate';
  private _tickInterval = 60000; // sixty seconds

  constructor(private _http: Http, protected _storage: AsyncLocalStorage) {
    this._timer = Observable.timer(this._tickInterval, this._tickInterval);
    this._sub = this._timer.subscribe(t => { this.timerInterval(t); });
  }

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

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

  // Get the stocks from the actual service or from local storage cache
  public getStockCache(): Promise<Stock[]> {
    console.error('getStockCache()');

    let result: Promise<Stock[]>;

    // Call the service if we have not before
    if (!this._lastStockCheckDate) {
      result = this.getStocks();
      this.saveToStorage(result);
      this.updateLastCheckDate();
    } else {
      // Get the data from storage
      result = <Promise<Stock[]>> this._storage.getItem(this._objectKey).toPromise();
    }

    return result;
  }

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

        // Google has a maximum of 60 seconds between calls
        if (lastStockCheckDate && (now.getTime() - lastStockCheckDate.getTime()) < this._tickInterval)  {
          return;
        }

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

        // Get the stocks from the service
        let serviceStockPromise: Promise<Stock[]> = this.getStocks();

        // If anything changed, save to local storage
        serviceStockPromise.then((serviceStocks) => {
          this._storage.getItem(this._objectKey).subscribe((storageStocks) => {
            if (this.anythingChanged(serviceStocks, storageStocks)) {
                this._storage.setItem(this._objectKey, serviceStocks)
                  .subscribe(() => {}, () => {});
            }
          }, () => {});
        });
      }, () => {});
  }

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

    if (serviceStocks.length !== storageStocks.length) {
      return true;
    }

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

    return false;
  }

  // Save what was returned from the service into local storage asynchronously
  private saveToStorage(stocks: Promise<Stock[]>): void {
    console.error('saveToStorage()');
    stocks.then((data) => {
      this._storage.setItem(this._objectKey, data)
        .subscribe(() => {}, () => {});
    });
  }

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



  // Get stocks from the service
  private getStocks(): Promise<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)))
    .toPromise();
  }

  // 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 个答案:

没有答案