How can i subscribe to multiple observables in angular2 at once and wait, if there is new data on each of them?

半城伤御伤魂 提交于 2021-02-07 12:24:17

问题


i have a angular component, that uses 3 services. Each of those services has an observer, that i can subscribe to. The view of the component must be updated, if anything on the observed changes, that happens through websockets (feathers.js). I want the doSomethingWithTheNewDataThatIsShownOnView() to be called only once on ngInit and i think, i can do this with 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();
}

That works as expected, but if there is new data on inputs$ Observable or outputs$ Observable, the subscribe is not beeing called again. It is only called, if all three Observables have new data. Is there something like "wait for a interval of 100ms if all three observables have new data, if not use only the new data of all observables, that have new data until now?"

I hope you understand, what i want to do :D

Greets

Chris


回答1:


combineLatest() should do the trick:

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();
}

Additional hints on your code:

As an alternative combineLatest() also takes an optional aggregation-method and also as a side-note: try to use pure functions only and avoid stateful components(this.inputs, this.outputs, ect..) and use the | async pipe in the template and try to avoid too much logic in the subscription and if possible try to avoid manual subscriptions at all, because those have to be manually unsubscribed but the async-pipe could handle that automatically for you:

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>


来源:https://stackoverflow.com/questions/41060371/how-can-i-subscribe-to-multiple-observables-in-angular2-at-once-and-wait-if-the

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!