代码之家  ›  专栏  ›  技术社区  ›  matsev

在没有下一个事件的情况下可以观察到rxjs?

  •  1
  • matsev  · 技术社区  · 6 年前

    我如何创建一个rxjs可观测的,只发出 complete 事件与否 next 事件?

    我有一个可观察的执行一些操作的副作用,它填充内存中的缓存。我想使用这个observate作为一个信号量,以便第二个observate只在它完成时才开始执行。然后第二个可观察对象可以使用这个缓存来修饰传入的数据。我的想法是利用 concat 第一次观测到的 完成 事件:

    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 过早完成,并且当第二个可观察对象尝试获取值时,缓存为空。值得注意的是,缓存将被填充 之后 装饰已经做了。
    • 删除skip时, 等待缓存 Observable将向 decorated 可观察的
    1 回复  |  直到 6 年前
        1
  •  0
  •   matsev    6 年前

    我决定重新实现我的解决方案,订阅这两个可观测数据,然后使用 filter 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]);
             }
          ));