What is the proper way to handle concatenation of data returned from multiple http observables in angular2/4 rxjs?

↘锁芯ラ 提交于 2019-12-24 10:53:36

问题


I have 5 different URLs that each return data in the from of an array of objects. I want to concat these objects into a single array that I store local to my ANgular2 componenent. Right now, I do something like this in my ngOnInit:

this.myHttpService.graburl1data()
    .subscribe(
        response => {
            if(!this.mylist) {
                this.mylist = []
                this.mylist = this.mylist.concat(response);
            } else {
                this.mylist = this.mylist.concat(response);
            }

            this.myHttpService.graburl2data()
                .subscribe(
                    response => {
                        if(!this.mylist) {
                            this.mylist = []
                            this.mylist = this.mylist.concat(response);
                        } else {
                            this.mylist = this.mylist.concat(response);
                        }
                    });
        });

There has to be a better way, please help!


回答1:


Suppose you have two requests and each returns an observable that emits an array as a stream value:

const response1 = of([1, 2, 3]);
const response2 = of([4, 5, 6]);

You want to get those values as a stream of values - flattened. You can use a combination of operators to do that:

const merged = merge(response1, response2).mergeMap((a) => {
  return a;
});

merged.subscribe((v) => {
  console.log(v);
});

You will get the following output:

1
2
3
4
5
6

In your case you will obtains the response observables by calling the http:

const response1 = this.myHttpService.graburl1data(),
const response2 = this.myHttpService.graburl2data()
...

So, the final code is:

import { merge } from 'rxjs/observable/merge';
import 'rxjs/add/operator/mergeMap';

const merged = merge(
  this.myHttpService.graburl1data(),
  this.myHttpService.graburl2data()
).mergeMap((a) => {
  return a;
});

merged.subscribe((v) => {
  console.log(v);
});



回答2:


Your snippet seems to suggest that there is no dependency between the requests, so you can use forkJoin to peform them in parallel:

import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/forkJoin";

Observable.forkJoin(
  this.myHttpService.graburl1data(),
  this.myHttpService.graburl2data()
)
.subscribe(
  (responses) => {
    // ... responses[0] is the response from this.myHttpService.graburl1data
    // ... etc.
  }
);

responses will be an array of the responses in the order in which the request observables were passed to forkJoin.

If you want the requests performed in series, use concat and toArray instead:

import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/concat";
import "rxjs/add/operator/toArray";

Observable.concat(
  this.myHttpService.graburl1data(),
  this.myHttpService.graburl2data()
)
.toArray()
.subscribe(
  (responses) => {
    // ... responses[0] is the response from this.myHttpService.graburl1data
    // ... etc.
  }
);


来源:https://stackoverflow.com/questions/45229733/what-is-the-proper-way-to-handle-concatenation-of-data-returned-from-multiple-ht

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