缓存数据,但在后台检查新数据

时间:2016-09-22 07:18:14

标签: http caching angular

我想缓存我的数据,但同时我需要我的数据是最新的。我发现了这个:Angular2 easiest way to cache HTTP responses但是这不会检查新数据。

我现在有这个服务:

public publishedSessions: Session[] = null;

  getPublishedSessions(): Observable<any> {
    let headers = new Headers();
    headers.append('authorization', this.userService.getToken());

    if (this.publishedSessions) {
      this.http.get(this.apiUrl + 'api/sessions/published', {
        headers: headers
      })
        .map(res => res.json().sessions)
        .subscribe(sessions => this.publishedSessions = sessions);

      return Observable.of(this.publishedSessions);
    } else {
    return this.http.get(this.apiUrl + 'api/sessions/published', {
      headers: headers
    })
      .do(res => this.publishedSessions = res.json().sessions)
      .map(res => res.json().sessions)
      .catch((error) => Observable.of(error));
    }
  }

我的组件中有一些标准代码:

handlePublishedSessions(): void {
     this.subscriptionArr.push(this.sessionService.getPublishedSessions().subscribe(sessions => {
      this.session = sessions
  }));
}

这会导致当我第一次导航(访问1)到页面时,将进行调用(调用1)(想要)。然后,如果我离开并返回页面(访问2),将返回来自呼叫1的数据(不想要),同时,呼叫2正在工作中。因此,如果我再次离开并导航回来(访问3),则返回来自呼叫2的数据。

我希望在前几毫秒访问2时显示呼叫1数据(直到完成呼叫2)。当完成调用2时,我希望替换数据(无需用户交互)。

1 个答案:

答案 0 :(得分:1)

我会使用BehaviorSubject来缓存数据。

看一下这个傻瓜得到一个想法:https://plnkr.co/edit/jNNQJToYia2MhIE488YX?p=preview

import {Component, NgModule, Injectable} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {HttpModule, Http} from '@angular/http';

import {BehaviorSubject} from 'rxjs/Rx';

@Injectable()
export class AnyService {

  public data = new BehaviorSubject<string>();

  constructor(private _http: Http) { }

  public getData(): string {
    this._http.get('https://httpbin.org/bytes/12')
      .subscribe(
        resp => this.data.next(resp._body)
      );
    return this.data.value;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2 (click)="getData()">Hello {{name}} -- CLICK ME !! --</h2>
    </div>
  `,
})
export class App {
  name:string;

  firstSubscribeCallback = false;

  constructor(private _srvc: AnyService) {
    this.name = 'Angular2'

    this._srvc.data.subscribe(
      newData => {

        // FIRST CALL WILL BE THE CACHED DATA..
        if (!this.firstSubscribeCallback) { // JUST FOR DEMO ..

          console.log('got cached data @ startup..');
          this.firstSubscribeCallback = true;

        }
        else console.log('got new data:');

        console.log(newData);
      }
    );

    this.getData(); // get FRESH data ..
  }

  getData() {
    console.log('getting cached data:');
    console.log(this._srvc.getData());
  }
}

@NgModule({
  imports: [ BrowserModule, HttpModule ],
  declarations: [ App ],
  providers: [ AnyService ],
  bootstrap: [ App ]
})
export class AppModule {}