加入一个返回的(promise-esq)Observable和一个全局可观察的

时间:2018-06-03 19:06:41

标签: javascript typescript rxjs reactive-programming readability

在我的网络应用程序的客户端代码中,我有一个类负责一堆websocket IO。这个类有一个全局itemUpdatedObservable,UI的各个部分都可以订阅它来做很少的事情。还有一个公共函数UpdateItem,它返回一个promise-esq Observable。当项目更新以响应对UpdateItem的调用时,我希望返回的observable和global observable都发出。返回的可观察量也应在发射后完成。

我已经提出了这个解决方案:

// Singleton
class API {

readonly itemUpdatedObservable: Observable<Item>;
private pendingItemUpdates: { [id: string]: Observer<Item> };

constructor() {
  this.itemUpdatedObservable = new Observable(observer => {
    socketio.on('itemUpdated', res => {
      // do a bunch of validation on item
      // ...

      if (!res.error) {
         observer.next(res.item);
      } else {
         observer.error(res.error);
      }

      let pendingObs = pendingItemUpdates[res.id]
      if (pendingObs) {
        if (!res.error) {
           pendingObs.next(res.item);
        } else {
           pendingObs.error(res.error);
        }
        pendingObs.complete()
        delete pendingItemUpdates[res.id];
      }
    })
  });
  this.pendingItemUpdates
}

public UpdateItem(item: Item): Observable<Item> {
  const o = new Observable(observer => {
    let id = uniqueId(); // Some helper somewhere.
    this.pendingItemUpdates[id] = observer;
    socketio.emit('updateitem', {item: item, id: id});
  }).publish();
  o.connect();
  return o;
}
}

我的问题是,是否有更简洁的方法可以做到这一点?除了itemUpdatedObservable之外,我还有10个以上的observable,它们都是不同Object类型的事件。这段代码很乱,很笨,特别是当我写它10倍以上时。有没有办法简化这两个可观察对象,以便我只调用observable.next(...)observable.error(...)一次?

上面的代码blob是我实际代码的简化,实际上有更多的验证和特定于上下文的值和参数。

1 个答案:

答案 0 :(得分:0)

也许您可以从创建一些可重用的socket函数开始,该函数返回observable。

const socketOn = (event) => {
   return Observable.create(obs => {
    socketio.on(event, res => {
      if (!res.error) {
        obs.next(res.item);
      } else {
        obs.error(res.error);
      }
    })
  }).share()
}

// usuage 
itemUpdated$=socketOn('itemUpdated')
itemUpdated$.map(res=>...).catch(e=>...)