如何使用RxJS在Angular 6中创建一系列HTTP请求

时间:2018-11-30 15:43:58

标签: angular typescript rxjs angular-httpclient rxjs6

我一直在网上寻找解决方案,但找不到适合我的用户情况的任何解决方案。我正在使用MEAN堆栈(角度6),并且有注册表。我正在寻找一种方法来执行对API的多个HTTP调用,每个依赖于前一个返回的结果。我需要这样的东西:

firstPOSTCallToAPI('url', data).pipe(
    result1 => secondPOSTCallToAPI('url', result1)
    result2 => thirdPOSTCallToAPI('url', result2)
    result3 => fourthPOSTCallToAPI('url', result3)
    ....
).subscribe(
    success => { /* display success msg */ },
    errorData => { /* display error msg */ }
);

我需要使用哪种RxJS运算符组合来实现此目的?一种可能的解决方案是嵌套多个订阅,但是我想避免这种情况,并使用RxJS更好地实现。还需要考虑错误处理...

感谢进阶!

6 个答案:

答案 0 :(得分:3)

试试看,Angular提供了一次调用多个API的功能。

forkJoin()

您将以与调用API相同的顺序在array中获取数据。

例如:

forkJoin(request1, request2)
    .subscribe(([response1, response2]) => {

您可以找到更多read

我还给了另外一个answer。请检查此内容,它也可能对您有帮助。

答案 1 :(得分:2)

对于取决于先前结果的呼叫,您应该使用concatMap

firstPOSTCallToAPI('url', data).pipe(
    concatMap(result1 => secondPOSTCallToAPI('url', result1))
      concatMap( result2 => thirdPOSTCallToAPI('url', result2))
       concatMap(result3 => fourthPOSTCallToAPI('url', result3))
    ....
).subscribe(
    success => { /* display success msg */ },
    errorData => { /* display error msg */ }
);

答案 2 :(得分:1)

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

@Injectable()
export class DataService {

  constructor(private http: HttpClient) { }

  public requestDataFromMultipleSources(): Observable<any[]> {
    let response1 = this.http.get(requestUrl1);
    let response2 = this.http.get(requestUrl2);
    let response3 = this.http.get(requestUrl3);
    return Observable.forkJoin([response1, response2, response3]);
  }
}

The above example shows making three http calls, but in a similar way you can request as many http calls as required

    import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";

@Component({
    selector: 'app-page',
    templateUrl: './page.component.html',
    styleUrls: ['./page.component.css']
})
export class DemoComponent implements OnInit {
    public responseData1: any;
    public responseData2: any;
    public responseData3: any;

    constructor(private dataService: DataService) {}

    ngOnInit() {
        this.dataService.requestDataFromMultipleSources().subscribe(responseList => {
            this.responseData1 = responseList[0];
            this.responseData2 = responseList[1];
            this.responseData3 = responseList[1];
        });
    }
}

答案 3 :(得分:1)

让我告诉您如何进行此操作,假设我有很多电子邮件要依次发送:

sendEmails() {
  this.isLoading = true; 
            const calls = this.emails <<-- assume this contain an array of emails
            .map(email => this.userEmailService.deliver({email: email, userId: 1242}));
            from(calls) <<-- make use of the from.
                .pipe(
                    concatMap(res => res),
                    finalize(() => this.isLoading = false)
                ).subscribe(() => { });
}

我希望这会有所帮助。

答案 4 :(得分:1)

我遇到了同样的问题,这是我的解决方案,使用 pipeconcatMap 作为数组来获取开始和结束时间之间的时间段的序列数据。

这是我们有数组请求时的通用解决方案。

我关心谁。

 let currentReplayData = [];
 let timerange = [[t1, t2], [t3, t4]]; // array of start and end time
 from(timerange).pipe(
      concatMap(time => <Observable<any>>this.dataService.getData(time[0],time[1]))
      ).subscribe(val => {
        //console.log(val)
        this.currentReplayData = this.currentReplayData.concat(val);
      });

答案 5 :(得分:0)

尚未提及的一种解决方案是使用 async/await:

KeyError: 'hist_equipo'