【问题标题】:rxjs - understand observable and observerrxjs - 理解 observable 和 observer
【发布时间】:2016-07-06 07:51:18
【问题描述】:

我无法理解 observable 和观察者 (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));

任何解释或任何页面的链接都会很棒,我了解 Array 等中的 map filter reduce 以及观察者模式,这很简单,但不是 RXJS 方式,这非常令人困惑!

非常感谢!

【问题讨论】:

  • 问题的新手,请查看observerobservable 的Rx 文档。它非常简单和全面。

标签: javascript angular rxjs


【解决方案1】:

这是观察者/可观察的样本:

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

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

观察者是用来触发一个事件的,而observable是用来接收它的。大多数时候,观察者是间隔使用的。例如通过 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 ]);

【讨论】:

  • 数据没有准备好怎么办?请在此处查看:jsbin.com/daxayuwinu/1/edit?js
  • 谢谢,我更新了代码以使用该方法显示组件,但是组件 ngOnInit 中的订阅者没有获取数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-26
  • 1970-01-01
  • 2017-11-13
相关资源
最近更新 更多