将 MergeMap 与从另一个可观察对象接收的数据数组一起使用 - RxJs Angular
Using MergeMap with the array of data received from another observable - RxJs Angular
我有一个 fetchDrives 方法,它将 return 一个可观察的对象,订阅后将 return 一个驱动器列表
this.fetchDrives(points).subscribe(drives => {
console.log(drives);
});
假设我订阅的驱动器阵列看起来像这样
[ {driveId: 1}, {driveId: 2}, {driveId: 3} ]
现在我需要通过将 driveId 传递给每个 api call.I 需要将 driveId 传递给下面的方法一次一个,获取纬度和经度,并将三个调用的结果存储在一个数组中。
this.getLatLong(driveId).subscribe( res => console.log(res))
res 将包含类似 { lat: 12, lon: 54 }
的对象
我不想进行两次订阅,有没有一种方法可以使用 Rxjs 运算符并通过使用先前可观察结果的一次订阅来实现此目的,遍历驱动器数组并调用三次 getLatLong
方法使用 mergeMap
作为调用顺序并不重要并将这三个调用的结果存储在数组中?
我尝试使用扫描运算符循环遍历但无法使用它获得所需的输出
提前感谢您的帮助:)
如果我对您的问题的理解正确,您想要展平驱动器阵列以迭代每个驱动器,然后进行 API 调用以获取每个驱动器的经纬度。
你可以用 mergeAll
和 mergeMap
运算符实现这样的事情。
您的代码应如下所示:
fetchDrives().pipe(
mergeAll(), // Flatten the drives array
mergeMap(drive => getLatLong(drive)) // Get each drive { lat, lon }
).subscribe(console.log)
您可以 运行 this stackblitz
中的完整示例
如果请求的顺序无关紧要,您可以使用 RxJS forkJoin
method to make the calls simultaneously. I've also used switchMap
运算符在源可观察对象 (this.fetchDrives(points)
) 发出后切换可观察对象。尝试以下
locations: any;
this.fetchDrives(points).pipe(
switchMap((drives) => {
let source = Object.create(null);
for (let i = 0; i < drives.length; i++) {
source[drives[i]['driveId']] = this.getLatLong(drives[i]['driveId']);
}
return forkJoin(source);
})
).subscribe(
response => {
this.locations = response;
},
error => {
// handle error
}
);
变量 locations
的形式为
// 'driveId': { lat: 12, lon: 54 }
{
'1': { lat: 12, lon: 54 },
'2': { lat: 12, lon: 54 },
'3': { lat: 12, lon: 54 }
}
更新:对象数组输出
到 return 来自 forkJoin
的对象数组,您可以发送一个可观察对象数组作为参数。例如。 forkJoin([obs1, obs2, ...])
。在前面的例子中,我们发送一个对象作为参数 (forkJoin({'name1': obs1, 'name2': obs2, ...})
,所以输出也将是一个对象。
locations: any = [];
this.fetchDrives(points).pipe(
switchMap((drives) => {
return forkJoin(drives.map(drive => this.getLatLong(drive['driveId'])));
})
).subscribe(
response => {
this.locations = response;
},
error => {
// handle error
}
);
locations
将采用
形式
[
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 }
]
我有一个 fetchDrives 方法,它将 return 一个可观察的对象,订阅后将 return 一个驱动器列表
this.fetchDrives(points).subscribe(drives => {
console.log(drives);
});
假设我订阅的驱动器阵列看起来像这样
[ {driveId: 1}, {driveId: 2}, {driveId: 3} ]
现在我需要通过将 driveId 传递给每个 api call.I 需要将 driveId 传递给下面的方法一次一个,获取纬度和经度,并将三个调用的结果存储在一个数组中。
this.getLatLong(driveId).subscribe( res => console.log(res))
res 将包含类似 { lat: 12, lon: 54 }
我不想进行两次订阅,有没有一种方法可以使用 Rxjs 运算符并通过使用先前可观察结果的一次订阅来实现此目的,遍历驱动器数组并调用三次 getLatLong
方法使用 mergeMap
作为调用顺序并不重要并将这三个调用的结果存储在数组中?
我尝试使用扫描运算符循环遍历但无法使用它获得所需的输出
提前感谢您的帮助:)
如果我对您的问题的理解正确,您想要展平驱动器阵列以迭代每个驱动器,然后进行 API 调用以获取每个驱动器的经纬度。
你可以用 mergeAll
和 mergeMap
运算符实现这样的事情。
您的代码应如下所示:
fetchDrives().pipe(
mergeAll(), // Flatten the drives array
mergeMap(drive => getLatLong(drive)) // Get each drive { lat, lon }
).subscribe(console.log)
您可以 运行 this stackblitz
中的完整示例如果请求的顺序无关紧要,您可以使用 RxJS forkJoin
method to make the calls simultaneously. I've also used switchMap
运算符在源可观察对象 (this.fetchDrives(points)
) 发出后切换可观察对象。尝试以下
locations: any;
this.fetchDrives(points).pipe(
switchMap((drives) => {
let source = Object.create(null);
for (let i = 0; i < drives.length; i++) {
source[drives[i]['driveId']] = this.getLatLong(drives[i]['driveId']);
}
return forkJoin(source);
})
).subscribe(
response => {
this.locations = response;
},
error => {
// handle error
}
);
变量 locations
的形式为
// 'driveId': { lat: 12, lon: 54 }
{
'1': { lat: 12, lon: 54 },
'2': { lat: 12, lon: 54 },
'3': { lat: 12, lon: 54 }
}
更新:对象数组输出
到 return 来自 forkJoin
的对象数组,您可以发送一个可观察对象数组作为参数。例如。 forkJoin([obs1, obs2, ...])
。在前面的例子中,我们发送一个对象作为参数 (forkJoin({'name1': obs1, 'name2': obs2, ...})
,所以输出也将是一个对象。
locations: any = [];
this.fetchDrives(points).pipe(
switchMap((drives) => {
return forkJoin(drives.map(drive => this.getLatLong(drive['driveId'])));
})
).subscribe(
response => {
this.locations = response;
},
error => {
// handle error
}
);
locations
将采用
[
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 }
]