【问题标题】:How can I wait for multiple subscriptions?如何等待多个订阅?
【发布时间】:2020-12-02 00:22:54
【问题描述】:

我正在尝试对数组的每个元素进行 API 调用,并在每个 API 响应为真时发出特定事件。

我正在做以下事情:

let emit = true

array.forEach(element => {
  this.service.getElement(element).subscribe(loaded => {
      if(!loaded){
         emit = false;
      }
  });
});

this.loaded.emit(emit);

但最后一行总是发出true

如何在发出输出事件之前等待每个请求都得到解决?

【问题讨论】:

标签: rxjs subscription


【解决方案1】:

因为调用http API是异步的,所以this.loaded.emit(emit)先执行;

修复:

let emit = true

array.forEach(element => {
  this.service.getElement(element).subscribe(loaded => {
      if(!loaded){
         emit = false;
         this.loaded.emit(emit);
      }
  });
});

如果要在所有 API 响应为真时执行this.loaded.emit(emit),请尝试使用forkJoin

【讨论】:

    【解决方案2】:

    所以最后一行总是会发出true,因为服务代码是异步执行的。这意味着它执行除了subscribe 方法中的回调函数之外的所有内容。一旦流发出新元素,就会执行此回调函数。我猜,您正在向此处的端点发出 Http 请求。如果是这样,则为每个Http响应执行回调函数,并且不保证顺序。

    你可以做的是:

    forkJoin(
      ...array.map(e => this.service.getElement(e))
    ).subscribe(responseArray =>
      console.log(responseArray);
      console.log('Complete');
    );
    

    只有在所有 Http 响应都可用时才会执行回调。并且responseArrayarray 中的元素具有完全相同的顺序。

    注意:请记住,如果你这样做了

    let emit = false;
    forkJoin(...).subscribe(() => emit = true);
    console.log(emit);
    

    它会打印你错误,因为回调执行异步。如果这对您来说似乎很奇怪,我强烈建议您阅读 JavaScript Eventloop。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-06
      • 2021-06-08
      • 1970-01-01
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 2022-07-05
      • 1970-01-01
      相关资源
      最近更新 更多