【问题标题】:Angular HttpClient: Make further api calls wait for the first one to finishAngular HttpClient:让进一步的 api 调用等待第一个完成
【发布时间】:2019-10-31 05:44:49
【问题描述】:

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

问题是,我的应用程序在启动时同时执行了一堆 api 调用,这导致调用具有无效会话 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 数据)。

【问题讨论】:

  • 我想你正在寻找forkjoin函数stackoverflow.com/questions/49327693/…
  • 你看过APP_INITIALIZER吗?您可以在其他功能之前运行您想要的单个功能...
  • @AJT_82 不错的提示!但我不希望我的应用程序启动等待/停止甚至基于此网络调用失败。如果尚未完成,我希望能够拨打等待第一个呼叫的呼叫。

标签: angular promise ionic3 observable


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    相关资源
    最近更新 更多