Присоединение к возвращаемой (обещание-esq) наблюдаемой и глобальной наблюдаемой - PullRequest
0 голосов
/ 03 июня 2018

В клиентском коде моего веб-приложения есть класс, отвечающий за связку ввода-вывода в сети.Этот класс имеет глобальный itemUpdatedObservable, на который могут подписаться различные части пользовательского интерфейса, чтобы делать мелочи.Существует также публичная функция UpdateItem, которая возвращает обещание-обещания.Когда элемент обновляется в ответ на вызов UpdateItem, я хочу, чтобы и возвращаемая наблюдаемая, и глобальная наблюдаемая излучали.Возвращаемая наблюдаемая также должна завершиться после испускания.

Я придумал это решение:

// 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;
}
}

Мой вопрос: есть ли более чистый и короткий способ сделать это?У меня есть что-то вроде 10+ наблюдаемых в дополнение к itemUpdatedObservable, что все они являются событиями для разных типов объектов.Этот код грязный и громоздкий, особенно когда я пишу его 10 раз.Есть ли способ упорядочить две наблюдаемые так, чтобы я звонил observable.next(...) или observable.error(...) только один раз?

Приведенный выше кодовый блок является упрощением моего реального кода, в действительности намного больше проверочных и зависящих от контекста значений и параметров.

1 Ответ

0 голосов
/ 04 июня 2018

Может быть, вы можете начать с создания некоторой многократно используемой функции сокета, которая возвращает наблюдаемую.

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=>...)
...