发送多个异步HTTP GET请求

时间:2017-01-12 17:22:06

标签: angular typescript observable

由于API不支持多项请求,因此我需要多次进行API调用。到目前为止我所写的内容最终会在向服务器发送GET请求的无限循环中结束。我相信我不明白下面例子中Observables的本质。我的假设是while循环中的每个调用都订阅一个新的单个对象,当它被解析时,它将被放置在数组中。如何修改以下代码以实现我想要的目标?

getSingle(): Observable<Single> {
    return this.http.get(this.url, this.options)
     .map((r: Response) => r.json().data as Single);
}

getMultiple(num: number): Single[] {
    let multiple: Single[] = [];

    let i = 0;
    while (i < num) {
        this.getSingle().subscribe(single => {
            multiple.push(single);
            console.log('Success');
            i++;
        }, err => {
            console.log('Failure');
        });
   }

   return multiple;
}

2 个答案:

答案 0 :(得分:2)

使用while循环来发出多个异步HTTP请求,然后单独订阅所有这些请求,以避免打开很多Observable个连接。我们可以使用Observable.forkJoin运算符。

这是实现的样子:

getSingle(singleUrl: string): Observable<Single> {
    return this.http.get(singleUrl, this.options)
        .map((r: Response) => r.json().data as Single);
};

getMultiple(): Observable<Array<Single>> {
    let singleUrls = ['singleUrl1', 'singleUrl2', 'singleUrl3']; // can be replaced with any 'Single' identifier

    let singleObservables = singleUrls.map((singleUrl: string, urlIndex: number) => {
        return this.getSingle(singleUrl)
            .map(single => single as Single)
            .catch((error: any) => {
                console.error('Error loading Single, singleUrl: ' + singleUrl, 'Error: ', error);
                return Observable.of(null); // In case error occurs, we need to return Observable, so the stream can continue
            });
    });

    return Observable.forkJoin(singleObservables);
};

this.getMultiple().subscribe(
    (singles: Array<Single>) => {
        console.log(singles); // [Single, Single, Single];
        // In case error occured e.g. for the 'singleUrl' (our 'Single' identifier) at position 1,
        // Output wil be: [Single, null, Single];
    }
);

希望这有帮助!

答案 1 :(得分:0)

理想情况下,您只能在构造函数中订阅一次,因为可以多次调用订阅块,然后在循环中使用RxJS主题和next()它

但是,如果你不太在意,快速修复就是:

this.getSingle().first().subscribe

您需要导入第一个运算符。这将确保仅订阅仅调用一次。这样你就可以多次担心。

我猜测你获得无限HTTP请求的原因是你的故障阻塞正在被击中而你需要做...

}, err => {
       i++;
        console.log('Failure');
 });