Наблюдения наблюдаются без следующих событий? - PullRequest
0 голосов
/ 26 июня 2018

Как я могу создать наблюдаемую RxJ, которая испускает только событие complete и никаких событий next?

У меня есть наблюдаемая, которая выполняет некоторые операции, что имеет побочный эффект, при котором она заполняет кэш в памяти.Я хотел бы использовать эту наблюдаемую в качестве семафора, чтобы вторая наблюдаемая начала выполняться только после ее завершения.Затем вторая наблюдаемая может использовать этот кэш для украшения входящих данных.Моя идея состоит в том, чтобы использовать concat , где первая наблюдаемая создает только событие complete:

const cache = {};
const firstObservable = // fetch data to be cached
const secondObservable = // fetch other data that will be decorated with cached data

// add all next events of the first observable to the cache
const promise = firstObservable
   .forEach(
      data => {
         cache[data.key] = data;
      }
   );

// create a new observable that only emits a complete event
const waitForCache = of(promise)
   .pipe(
      // skip the first event from waitForCache (the empty promise event), 
      // since we are only interested in when the population of the cache is complete
      skip(1)
   );

// create a semaphore that waits for the complete event from the cache population 
// before dealing with the second observable
const decorated = concat(waitForCache, secondObservable)
   .pipe(
      map(
         data => {
            // decorate objects with data from cache
            return Object.assign({}, data, cache[data.key]);
         }
      ));

Я предполагаю, что проблема заключается в вызове skip(1).

  • При реализации, приведенной выше, waitForCache завершается слишком рано, и кэш-память пуста, когда вторая наблюдаемая пытается получить значение.Примечательно, что кэш будет заполнен после украшения было сделано.
  • При удалении пропуска наблюдаемая waitForCache добавит дополнительное (пустое) событие к наблюдаемой decorated

1 Ответ

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

Я решил повторно реализовать свое решение, чтобы подписаться на обе наблюдаемые, а затем использовать фильтр , чтобы отбросить события из firstObservable (которые были добавлены в кэш), чтобы только события изsecondObservable зависит от функции отображения:

const cache = {};
const firstObservable = // fetch data to be cached
const secondObservable = // fetch other data that will be decorated with cached data

// add all next events of the first observable to the cache
const waitForCache = firstObservable
   .pipe(
      tap({
         next: data => {
            cache[data.key] = data;     
         }
      });

// use concat so the cache population is completed before dealing with the second observable
const decorated = concat(waitForCache, secondObservable)
   .pipe(
      filter(
         data => { return /* check for some specific property that is 
                             available in one observable, but not the other */ } 
      )
      map(
         data => {
            // decorate objects with data from cache
            return Object.assign({}, data, cache[data.key]);
         }
      ));
...