在Angular中解析多个API调用

时间:2018-08-22 11:41:20

标签: angular observable angular2-observables

我试图在使用Resolve加载组件之前调用3个不同的API。

下面的这段代码写在resolve函数内部,并且返回一个包含所有响应的对象。

现在,当组件加载时,在我从服务器接收响应之前。它为返回的对象中的每个键返回null。

请帮助我如何解决此类问题。在收到未从API收到响应之前,如何阻止它返回。

resolve() {
  this._apiFactory.getA().subscribe(response => {
     responseA = response;
  });
  this._apiFactory.getB().subscribe( response => {
     responseB = response;
  });
  this._apiFactory.getC().subscribe( response => {
     responseC = response;
  });

  return {
    'A': responseA ,
    'B': responseb ,
    'C': responseC 
  };
}

4 个答案:

答案 0 :(得分:1)

您要在完成订阅之前返回。使用Fork Join等到所有Get请求都完成后,再以您要求的格式返回get请求的结果。

resolve() {
    let join = Observable.forkJoin(
      this._apiFactory.getA().map(),
      this._apiFactory.getB().map(),
      this._apiFactory.getC().map()
    )

    return join.map(
      ([responseA, responseB, responseC]) => {
        return {
          'A': responseA ,
          'B': responseb ,
          'C': responseC 
        }
      }
    ).first()
}

编辑: 我在Angular 6中尝试过,并且能够做到:

// dummy Observables
let a  = of([1]).pipe(delay(1000));
let b  = of([1, 2, 3]).pipe(delay(2000));
let c  = of([1, 2, 3, 4]).pipe(delay(3000));

 let join = forkJoin(a,b,c).pipe(map((allResponses) => {
   return {
     A: allResponses[0],
     B: allResponses[1],
     C: allResponses[2]
   };
 }));

 return join;

因此,我操纵了forkJoin中的数据并返回了forkJoin本身。在这里查看:https://stackblitz.com/edit/angular-xepafp?file=src%2Fapp%2FAPIResolver.ts

在angular2中,类似这样的方法应该起作用(也请尝试从map下的Observables中删除forkJoin并查看..):

resolve() {
    return Observable.forkJoin(
      this._apiFactory.getA().map(),
      this._apiFactory.getB().map(),
      this._apiFactory.getC().map()
    ).map((allResponses) => {
       return {
         A: allResponses[0],
         B: allResponses[1],
         C: allResponses[2]
       };
     })
}

答案 1 :(得分:1)

从RxJS 6.5+开始,方法是:

return forkJoin({
  todos: timer(500).pipe(mapTo([{ title: 'forkJoin'}])),
  user: timer(500).pipe(mapTo({ id: 1 }))
});

答案 2 :(得分:0)

这也可以通过combineLatest完成。参见this stackblitz

import { Injectable } from "@angular/core";
import { Resolve, ActivatedRouteSnapshot } from "@angular/router";
import { of, combineLatest } from "rxjs";
import { delay } from "rxjs/operators";

@Injectable({
  providedIn: "root"
})
export class TestResolver implements Resolve<any> {
  constructor() {}

  resolve(route: ActivatedRouteSnapshot) {
    let a = of([1]).pipe(delay(1000));
    let b = of([1, 2, 3]).pipe(delay(2000));
    let c = of([1, 2, 3, 4]).pipe(delay(3000));

    return combineLatest(a, b, c);
  }
}

答案 3 :(得分:0)

请不要使用“订阅”,您可以将观测值返回为

let a= observable(1);
let b= observable(2);
let c= observable(3);
return forkJoin(a,b,c);

这将为您提供帮助