我有一个角度组件,它使用3个服务。每个服务都有一个观察者,我可以订阅。如果通过websockets(feathers.js)发生观察到的更改,则必须更新组件的视图。
我想在ngInit上只调用doSomethingWithTheNewDataThatIsShownOnView()
一次,我想,我可以用forkJoin做到这一点:
private ngOnInit(): void {
Observable.forkJoin(
this.filesService.inputs$,
this.filesService.outputs$,
this.processesService.items$
).subscribe(
data => {
this.inputs = data[0];
this.outputs = data[1];
this.processes = data[2];
this.doSomethingWithTheNewDataThatIsShownOnView();
this.ref.markForCheck();
},
err => console.error(err)
);
this.filesService.find();
this.processesService.find();
}
按预期工作,但如果输入$ Observable或输出$ Observable有新数据,则不会再次调用subscribe。如果所有三个Observable都有新数据,则仅调用它。是否存在类似"如果所有三个可观测数据都有新数据,则等待100毫秒的间隔,如果不使用所有可观察数据的新数据,那么到目前为止还有新数据?"
我希望你明白,我想做什么:D
迎接
克里斯
答案 0 :(得分:14)
combineLatest()
应该这样做:
private ngOnInit(): void {
Observable.combineLatest(
this.filesService.inputs$,
this.filesService.outputs$,
this.processesService.items$
).subscribe(
data => {
this.inputs = data[0];
this.outputs = data[1];
this.processes = data[2];
this.doSomethingWithTheNewDataThatIsShownOnView();
this.ref.markForCheck();
},
err => console.error(err)
);
this.filesService.find();
this.processesService.find();
}
您的代码的其他提示:
作为替代方案combineLatest()
也采用可选的聚合方法,也作为旁注:尝试仅使用纯函数并避免使用有状态组件(this.inputs
,this.outputs
等..)并在模板中使用| async
管道并尝试避免订阅中的太多逻辑,如果可能的话,尽量避免手动订阅,因为那些必须手动取消订阅但async
-pipe可以自动为您处理:
autoUpdatedViewData$ = Observable.combineLatest(
this.filesService.inputs$,
this.filesService.outputs$,
this.processesService.items$,
(inputs, outputs, items) => ({inputs, outputs, items})
)
.map(({inputs, outputs, items}) => {
return this.doSomethingWithTheNewDataThatIsShownOnView(inputs, outputs, items);
});
private ngOnInit(): void {
this.filesService.find();
this.processesService.find();
}
// in your template
<div>{{autoUpdatedViewData$ | async}}</div>