如何等待多个订阅?

时间:2020-08-12 09:09:41

标签: rxjs subscription

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

我正在做以下事情:

let emit = true

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

this.loaded.emit(emit);

但是最后一行总是发出true

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

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:-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响应都为true时执行this.loaded.emit(emit),请尝试使用forkJoin