Angular HttpClient:进行进一步的api调用,以等待第一个API完成

时间:2019-06-17 15:34:58

标签: angular promise ionic3 observable

我有一个使用登录cookie的应用程序,该cookie与大多数api请求/调用一起发送以验证用户。 (由成功登录后由服务器设置。)

问题是,我的应用程序在启动时同时进行了大量的api调用,导致使用无效会话ID进行的调用,然后为每个调用在服务器端重新创建了会话ID,因此它们最终具有不同的会话ID =>用户注销。

我的计划是在彼此允许之前发送一个api调用。但是不知何故我无法使其按正确的顺序工作。

我想出了一个承诺,它将在我的包装构造函数中的第一个调用完成后得到解决

private firstCallMade: Promise<any>;

constructor(
    private http: HttpClient,
    private settings: SettingsProvider)
  {    
    this.settings.getAsyncString("apiEndpoint").then(res =>
    {
      this.apiUrl = res;

      this.firstCallMade = new Promise((resolve, reject) =>
      {
        this.http.get(this.apiUrl + this.firstCallEndpoint, { withCredentials: true })
        .subscribe(
          (result) => {
            this.logger.system(this, 'First Call', `First call successful: ${JSON.stringify(result)}`);
            resolve();
          },
          (error) => {
            this.logger.system(this, 'First Call', `First call failed: ${JSON.stringify(error)}`);
            resolve();
          });
      });
    });
  }

在其他包装方法中,我像这样使用它

  get<T>(endpoint: string): Observable<T>
  {
    return new Observable<T>(subscriber =>
    {
      this.firstCallMade.then(_ =>
      {
        this.http.get<T>(this.apiUrl + endpoint)
          .subscribe(
            next => subscriber.next(next),
            error => subscriber.error(error));
      });
    });
  }

但这不起作用。

我的代码错误吗?

编辑说明 所需要的就是全部,但是第一个调用可以同时进行, 完成后(因此为后续调用设置正确的cookie数据)。

1 个答案:

答案 0 :(得分:1)

1您不需要forkJoin,需要mergeMap或concatMap,forkJoin通常很差,为什么?因为如果一个请求失败,那么其他一切都会失败。

mergeMap和concatMap,例如,如果十个请求之一失败,则其他九个继续尝试完成。

mergeMap和concatMap之间的区别在于它们执行请求的方式,在mergeMap中,它们是通过“一键式”发送到服务器的,我的意思是,让我们以为您要拉10个日期,mergeMap然后为这10个日期不等待上一个日期完成,而concatMap等待上一个日期完成以向队列添加新请求。

这里有一个示例“如何使用concatMap,mergeMap和forkJoin”:https://angular-bojdob.stackblitz.io

这里是来自Tomas(英语):https://blog.angularindepth.com/practical-rxjs-in-the-wild-requests-with-concatmap-vs-mergemap-vs-forkjoin-11e5b2efe293