如何在angular2中同时订阅多个observable并等待,如果每个都有新的数据?

Chr*_*ter 4 reactive-programming observable rxjs typescript angular

我有一个角度组件,使用3个服务.每个服务都有一个观察者,我可以订阅.如果通过websockets(feathers.js)发生观察到的更改,则必须更新组件的视图.我想doSomethingWithTheNewDataThatIsShownOnView()在ngInit上只调用一次,我想,我可以用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();
}
Run Code Online (Sandbox Code Playgroud)

这可以按预期工作,但如果输入$ Observable或输出$ Observable有新数据,则不会再次调用subscribe.如果所有三个Observable都有新数据,则仅调用它.是否存在类似"等待100ms的间隔,如果所有三个可观测数据都有新数据,如果不使用所有可观察数据的新数据,到目前为止都有新数据?"

我希望你明白,我想做什么:D

电贺

克里斯

ols*_*lsn 16

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();
}
Run Code Online (Sandbox Code Playgroud)

您的代码的其他提示:

作为替代方案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>
Run Code Online (Sandbox Code Playgroud)