观察者订阅RxJS ipe

时间:2019-12-06 05:54:53

标签: rxjs

我有一个可以观察到的RxJS可见生成方法,但是似乎有点不可靠,我想知道是否可以通过更好地使用RxJs运算符来改进它。

我实现的是一个对象缓存(在Angular服务中),在该对象缓存中,当对象被加载,编辑或更改时会生成事件。事件对象如下所示:

export interface DNodeEvent {
  type: 'load' | 'unload' | 'update' | 'create' | 'error';
  node: DNode;
}

因此,我有一种方法,可生成可观察的组件供使用。调用方提供一个ID /序列号并获取节点对象流。我当前的代码如下:

  obById(id: number): Observable<DNode> {
    const unload = { type: 'unload' } as DNode;
    const pipeId =  this.nodeEvent$.pipe(
      filter(ne => ne.node.serial === id &&
        (ne.type === 'load' || ne.type === 'update')),
      map(ne => ne.node)
    );
    const pipeLoad = of(id).pipe(
      tap(loadTarget => this.loadId(loadTarget)),
      switchMap(loadTarget => of(unload)),
      filter(dn => dn.type === 'load')
    );
    return merge(pipeId, pipeLoad);
  }

可观察到的pipeId会生成节点流,但我看不到有什么改进之处。

然而,pipeload的功能是调用this.loadId方法,该方法触发从nodeEvent$主题生成事件。如果它在缓存中找到请求的对象,它将立即发送一个事件,否则它将订阅一个http可观察到的从服务器获取的对象,然后生成事件。

我唯一的问题是我不希望pipeLoad发出任何东西。但是我最后将switchMap / filter运算符放在那里以完成of运算符。另外,我不得不在其中贴上笨拙的unload常量,以防止编译器抱怨类型匹配。

是否有更优雅/更强大的方法来完成此任务?

2 个答案:

答案 0 :(得分:2)

您可以将ignoreElements()设为静音,但仍然订阅该流。

const pipeLoad = of(id).pipe(
  tap(loadTarget => this.loadId(loadTarget)),
  switchMap(loadTarget => of(unload)),

  ignoreElements()
);

答案 1 :(得分:0)

我不明白这样做的目的:

     List<String> a = [];
        a.add("123");
        a.add("444");

        var table = await mydb.rawQuery(
            "SELECT value from employee  WHERE employeename = ? AND id NOT IN ? ORDER BY timestamp DESC",
            ["max", a]);

这样做会不会一样?

const unload = { type: 'unload' } as DNode;

...
const pipeLoad = of(id).pipe(
  tap(loadTarget => this.loadId(loadTarget)),
  switchMap(loadTarget => of(unload)),          <--- ?
  filter(dn => dn.type === 'load')              <--- ?
);

return merge(pipeId, pipeLoad);

更新:

使用上面建议的代码使用obById(id: number): Observable<DNode> { const pipeId$ = this.nodeEvent$.pipe( filter(ne => ne.node.serial === id && (ne.type === 'load' || ne.type === 'update')), map(ne => ne.node) ); this.loadId(id); return pipeId$; } 代替BehaviorSubject可以解决此问题。我试图在Stackblitz中重现您的代码,请检查here