当第二个请求依赖第一个请求时,如何在Angular中同步http.get请求?

时间:2019-07-18 12:07:20

标签: javascript angular typescript

我需要从Angular向我的数据库执行一系列HTTP请求。第一步,我得到一个对象数组。一切正常。 在第二步中,我想用其他数据填充每个对象。因此,我需要等待第一个http.request完成。 我也不想在获取数据之前返回。

我的函数getData()应该返回一个Observable,因为接口/签名不应该更改(因为它在程序的其他部分中使用,并且observable对程序逻辑有意义)。

// Returns an array with objects, that have an id, that is needed for the second call 

data[] : Object = new Array(); 
populatedData[] : Object = new Array();


getData(): Observable<Object[]>{
  this.http.get<Object[]>("http://localhost:3000/data").subscribe(data => this.data = data);

// This needs the data from the first call 
 for(int i = 0; i < data.length; i++){
this.http.get<Object>("http://localhost:3000/data/"+data[i].id).subscribe(data => populatedData.push(data)); 
}


return of(populatedData); 

}

4 个答案:

答案 0 :(得分:2)

您可以使用switchMap(完成初始GET之后,发出其他请求)和forkJoin(发出多个请求并在所有请求完成时发出)。像这样:

    getSingleEntry = ({ id }) => this.http.get<Object[]>("http://localhost:3000/data/" + id);

    getData = () => this.http.get<Object[]>("http://localhost:3000/data")
        .pipe(
            tap(data => this.data = data),
            switchMap(data => forkJoin(data.map(this.getSingleEntry)));

答案 1 :(得分:1)

Promise是一个选项,但另一个选项可以是

// Returns an array with objects, that have an id, that is needed for the second call 
   data[] : Object = new Array(); 
   populatedData[] : Object = new Array();

  getData(): Observable<Object[]>{
     this.http.get<Object[]>("http://localhost:3000/data").subscribe((data)=>{
      this.data = data;
             for(int i = 0; i < data.length; i++){
                  this.http.get<Object>("http://localhost:3000/data/"+data[i].id).subscribe((response)=> {
                          populatedData.push(response)
                   }); 
             }
         });
      return of(populatedData); 
    }

答案 2 :(得分:0)

我认为最好的方法是使用switchMap RXJS运算符和zip。在第二次通话中,您可以访问第一个通话中的数据。然后,您可以在完成所有调用后返回值数组。

有关switchMap的更多信息,您可以阅读here。关于zip here

这里有一个示例,数据如何显示为https://rxviz.com/v/Mogdv96O

然后您的代码将被重构如下:

  getData(): Observable<Object[]> {
    this.http.get<Object[]>("http://localhost:3000/data")
      .pipe(switchMap((data) =>
              zip(...data.map(item => this.http.get<Object>("http://localhost:3000/data/" + item.id)))
            )
      );
  }

答案 3 :(得分:-1)

您应该将需要第一次调用的代码放入第二次

data: Array<any> = []; 
populatedData: Array<any> = []; 



getData(): Observable<Object[]> {
    this.http.get<Object[]>('http://localhost:3000/data').subscribe(data => {
        this.data = data;
        for (let i = 0; i < data.length; i++) {
            this.http
                .get<Object>('http://localhost:3000/data/' + data[i].id)
                .subscribe(data => populatedData.push(data));
        }
    });

    return of(populatedData);
}