我有一个可以观察到的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
常量,以防止编译器抱怨类型匹配。
是否有更优雅/更强大的方法来完成此任务?
答案 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。