如何等待多个订阅?
How can I wait for multiple subscriptions?
我正在尝试对数组的每个元素进行 API 调用,并在每个 API 响应为真时发出特定事件。
我正在做以下事情:
let emit = true
array.forEach(element => {
this.service.getElement(element).subscribe(loaded => {
if(!loaded){
emit = false;
}
});
});
this.loaded.emit(emit);
但最后一行总是发出 true
如何在发出输出事件之前等待每个请求都得到解决?
所以最后一行总是发出 true
因为服务代码是异步执行的。这意味着它会执行除 subscribe
方法中的回调函数之外的所有内容。一旦流发出新元素,就会执行此回调函数。我想,您正在向此处的端点发出 Http 请求。如果是这样,回调函数针对每个Http响应执行,顺序不保证。
您可以做的是:
forkJoin(
...array.map(e => this.service.getElement(e))
).subscribe(responseArray =>
console.log(responseArray);
console.log('Complete');
);
回调仅在所有 Http 响应可用时执行。并且 responseArray
与 array
.
中的元素具有完全相同的顺序
注意:请记住,如果您这样做
let emit = false;
forkJoin(...).subscribe(() => emit = true);
console.log(emit);
它会打印出 false,因为回调执行异步。如果这对您来说似乎很奇怪,我强烈建议您阅读有关 JavaScript Eventloop 的内容。
因为调用 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
。
我正在尝试对数组的每个元素进行 API 调用,并在每个 API 响应为真时发出特定事件。
我正在做以下事情:
let emit = true
array.forEach(element => {
this.service.getElement(element).subscribe(loaded => {
if(!loaded){
emit = false;
}
});
});
this.loaded.emit(emit);
但最后一行总是发出 true
如何在发出输出事件之前等待每个请求都得到解决?
所以最后一行总是发出 true
因为服务代码是异步执行的。这意味着它会执行除 subscribe
方法中的回调函数之外的所有内容。一旦流发出新元素,就会执行此回调函数。我想,您正在向此处的端点发出 Http 请求。如果是这样,回调函数针对每个Http响应执行,顺序不保证。
您可以做的是:
forkJoin(
...array.map(e => this.service.getElement(e))
).subscribe(responseArray =>
console.log(responseArray);
console.log('Complete');
);
回调仅在所有 Http 响应可用时执行。并且 responseArray
与 array
.
注意:请记住,如果您这样做
let emit = false;
forkJoin(...).subscribe(() => emit = true);
console.log(emit);
它会打印出 false,因为回调执行异步。如果这对您来说似乎很奇怪,我强烈建议您阅读有关 JavaScript Eventloop 的内容。
因为调用 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
。