rxjs - 理解可观察和观察者

时间:2016-03-19 15:08:33

标签: javascript angular rxjs

我无法理解observable和observer(rxjs),我知道observable可以将消息发送给观察者,观察者可以订阅observable,但我不知道如何设置它?

让我说我想请求URL,第一次用户调用“loadData”,数据从http请求加载,并在类内部保存,下次用户调用“loadData”时,我们不想加载从http,但在本地获取数据,但我想使用相同的代码“loadData”,它应该返回Observer,所以开发人员不知道数据的加载位置和方式!

let data = [];
function loadData():Observer {
   var observer = new Observer();
   if (data.length > 0) {
      var observable = new Observable.from(data);
      observable.add(observer);
      observable.notify();
   } else {
      var observable = this.http.get("data.json");
      observable.add(observer);
      observable.readyData( (data) => { 
         this.data = data; 
         observable.notify(); 
      };
  }
}

var observer = loadData();
observer.dataComing((data) => console.log(data));

对任何页面的任何解释或链接都会很棒,我理解数组等中的地图过滤器减少,以及容易的观察者模式,但不是RXJS方式,这非常令人困惑!

非常感谢!

1 个答案:

答案 0 :(得分:2)

以下是观察者/观察者的样本:

var obs = Observable.create((observer) => {
  setTimeout(() => {
    observer.next('some event');
  }, 1000);
});

obs.subscribe((event) => {
  // The event is received here
});

观察者用于触发事件,而观察者则用于接收事件。大多数时候,观察者是使用间隔。例如,通过Angular2的HTTP支持

以下是有关反应式编程的一些链接:

对于您的特殊用例,您可以使用:

loadData(url:string):Observable {
  if (this.cachedData) {
    return Observable.of(this.cachedData);
  } else {
    return this.get(...).map(res => res.map()).do((data) => {
      this.cachedData = data;
    });
  }
}

修改

我会以这种方式重构您的代码:

@Injectable()
export class LoungesService {
  constructor(private http:Http) {
    this.loungesByCity = {};
  }

  getLoungesByCity(city:City):Observable<any> {
    if (this.loungesByCity && this.loungesByCity[city.id]) {
      return Observable.of(this. loungesByCity[city.id]);
    } else {
      return this.http.get("lounges.json")
          .map(res => <Lounge[]> res.json().data)
          .map((lounges) => {
            return lounges.filter((lounge) => lounge.city_id === city.id);
          })
          .do(data => this.loungesByCity[city.id] = data);
  }
}

请注意,在引导您的应用程序时,必须将LoungesService定义为共享服务:

bootstrap(AppComponent, [ LoungesService ]);