Angular4使用Rxjs5共享Http请求返回的结果数据

在使用Angular开发的单页面应用里,有时需要处理这种场景:使用http请求某个数据,数据请求成功后需要把数据更新到多个组件里。也就是说,有多个observer(观察者)对http请求数据返回的Observable订阅。

getDta() {
    return this.http.get('/dataUrl').map(res => res.json());
}
let dataObservable = getDta();

let subscriber1 = dataObservable.subscribe(...);
let subscriber2 = dataObservable .subscribe(...);

如果代码类似上面这样写,你会发现http发了两次请求。这明显和我们的设想有出入,我们是希望http请求完后共享请求的数据。

这里分为两种场景:

  1. 请求的数据是固定不变的,可以考虑把请求的数据缓存起来

请求数据后是要同时更新多个组件,下次需要重新请求再更新相应的组件

缓存共享数据

对于请求数据是固定不变的或者是在一段时间内不会发生修改,可以考虑把数据缓存起来。

示例:

import {Injectable} from '@angular/core';
import {Http, Headers} from '@angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of'; //proper way to import the 'of' operator
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/map';
import {Data} from './data';

@Injectable()
export class DataService {
  private url:string = 'https://cors-test.appspot.com/test';

  private data: Data;
  private observable: Observable<any>;

  constructor(private http:Http) {}

  getData() {
    if(this.data) {
      //数据已存在,返回数据的Observable
      return Observable.of(this.data); 
    } else if(this.observable) {
      //数据还没有返回,正在请求中,返回该请求的observable
      return this.observable;
    } else {
      //还没有发起请求,发起http请求。
      this.observable = this.http.get(this.url)
      .map(response =>  {
        //数据返回后,此次的observable不再需要,下次访问返回data的Observable
        this.observable = null;
        if(response.status == 400) {
          return "FAILURE";
        } else if(response.status == 200) {
          this.data = new Data(response.json());
          return this.data;
        }
      })
      .share();//使用share(),允许多个订阅获取结果
      return this.observable;
    }
  }
}

多组件共享每次请求的数据

对于每次请求的数据可能会被修改,那么就不适合缓存数据了。

Rxjs 5.4.0新增了shareReplay()函数,可以使用它来共享http ajax请求的数据

示例

getDta() {
    return this.http.get('/dataUrl').map(res => res.json()).shareReplay();
}
let dataObservable = getDta();

参考:https://stackoverflow.com/questions/36271899/what-is-the-correct-way-to-share-the-result-of-an-angular-2-http-network-call-in

版权声明:著作权归作者所有。

相关推荐

Django响应http请求返回JSON数据

首先使用字典结构存放数据,例如返回错误信息:import json from django.http import HttpResponse response_data = {} response_data['result'] = 'error' response_data['message'] =&nb

Python解析http请求返回的JSON响应

python解析JSON响应可以使用以下两种方式:1、json.loadsimport json import requests response = requests.get(...) json_data = json.loads(response.text) 这种方法会把字符串转换为字典类型,这样就可以向json一样访问对象。2、r

Angular4 监听路由URL的变化

Angular 4检测路由变化,可以使用router.events来监听:支持的事件类型:NavigationStart:导航开始NavigationEnd:导航结束NavigationCancel:取消导航NavigationError:导航出错RoutesRecoginzed:路由已认证在判断事件类型需要导入对应的事件类型,如:import { Router,&n

Angular 5配置使用service-worker

Angular 5实现了一个适用于Angular应用的Service Worker,Angular CLI 1.6也添加了对service worker的支持。使用Angular CLI对应用添加service worker的支持分两种情况:新项目应用中添加service worker在已有项目中添加service&n

Html5使用localStorage存储对象数据

Html5可使用localStorage存储数据,其方法为storage.setItem(keyName, keyValue); 其中:keyName:键,字符串类型keyValue:值,字符串类型关于setItem,可以参考:Storage.setItem()。如果需要存储对象数据,那么需要把对象数据使用JSON.stringify转换为字符串。localStorage.setItem