【问题标题】:Resolve in Angular for multiple api calls在 Angular 中解析多个 api 调用
【发布时间】:2018-08-22 11:41:19
【问题描述】:

我试图在使用 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 
  };
}

【问题讨论】:

标签: angular observable angular2-observables


【解决方案1】:

您在订阅完成之前返回。使用Fork Join 等待您的所有Get 请求完成,然后以您所需的格式返回get 请求的结果..

更新

从 Rxjs 6.5.0 开始,forkJoin 也接受一个对象作为参数。

// dummy Observables
const obsArg = {
    A: of([1]).pipe(delay(1000)),
    B: of([1, 2, 3]).pipe(delay(2000)),
    C: of([1, 2, 3, 4]).pipe(delay(3000))
}

return forkJoin(obsArg)

我在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 中,这样的东西应该可以工作:

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

【讨论】:

  • 感谢 Aashish,但它仍然没有帮助。如您所见,这是我第一次使用的路由器解析方法。而且我看到路由器返回一个嵌套的可观察对象,而不是在 forkJoin 结束之前返回这个对象
  • @JEETADHIKARI:查看更新,我从stackoverflow.com/questions/39066604/… 获取的,我认为 first() 在这里应该没问题。
  • 嘿阿什什。非常感谢。这解决了问题。 :)
【解决方案2】:

从 RxJS 6.5+ 开始,方法是:

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

【讨论】:

    【解决方案3】:

    这也可以通过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);
      }
    }
    

    【讨论】:

      【解决方案4】:

      请不要使用订阅,而是可以将您的可观察对象返回为

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

      这对你有帮助

      【讨论】:

        猜你喜欢
        • 2018-03-23
        • 1970-01-01
        • 2017-08-14
        • 2021-04-22
        • 1970-01-01
        • 1970-01-01
        • 2018-01-30
        • 2016-08-25
        • 1970-01-01
        相关资源
        最近更新 更多