[英]Using MergeMap with the array of data received from another observable - RxJs Angular
I have a fetchDrives method which will return an observable which on subscription will return a list of drives我有一个 fetchDrives 方法,它会返回一个 observable,订阅时会返回一个驱动器列表
this.fetchDrives(points).subscribe(drives => {
console.log(drives);
});
Assume The drives array which I got on subscription look some what like this假设我订阅的驱动器阵列看起来像这样
[ {driveId: 1}, {driveId: 2}, {driveId: 3} ]
Now I need to use the driveId one by one and make three calls ( three because length of the drives array is 3 ) by passing driveId to each api call.I need to pass driveId to the below method one at a time and get the lat and lon and store the result of three calls in an array.现在我需要通过将 driveId 传递给每个 api 调用来逐个使用 driveId 并进行三个调用(三个调用,因为驱动器数组的长度为 3)。我需要一次将 driveId 传递给以下方法并获取 lat和 lon 并将三个调用的结果存储在一个数组中。
this.getLatLong(driveId).subscribe( res => console.log(res))
The res will contain an object like { lat: 12, lon: 54 }
res 将包含一个 object 像
{ lat: 12, lon: 54 }
I don't want to do two subscriptions, is there a way I can use the Rxjs operators and achieve this with one subscription using the result of previous observable, loop through the drives array and make three calls to getLatLong
method using mergeMap
as the sequence of the calls doesn't matter and store the result of those three calls in an array?我不想进行两次订阅,有没有办法可以使用 Rxjs 运算符并使用先前可观察的结果通过一次订阅来实现此目的,循环遍历驱动器数组并使用
mergeMap
作为序列对getLatLong
方法进行三次调用调用无关紧要并将这三个调用的结果存储在数组中?
I tried using scan operator to loop through but failed to use it to get the desired output我尝试使用扫描运算符循环但未能使用它来获得所需的 output
Thanks for the help in advance:)我在这里先向您的帮助表示感谢:)
If I understood your question correctly, you want to flatten drives array in order to iterate each drive, and then make API call to get each drive lat lon.如果我正确理解了您的问题,您想要展平驱动器阵列以迭代每个驱动器,然后进行 API 调用以获取每个驱动器 lat lon。
You can achieve such thing with mergeAll
and mergeMap
operators.您可以使用
mergeAll
和mergeMap
运算符来实现这样的事情。
Your code should look something like this:您的代码应如下所示:
fetchDrives().pipe(
mergeAll(), // Flatten the drives array
mergeMap(drive => getLatLong(drive)) // Get each drive { lat, lon }
).subscribe(console.log)
You can run the full example in this stackblitz您可以在此 stackblitz中运行完整示例
If the order of the requests doesn't matter, you could use RxJS forkJoin
method to make the calls simultaneously.如果请求的顺序无关紧要,您可以使用 RxJS
forkJoin
方法同时进行调用。 I've also used switchMap
operator to switch the observable once the source observable ( this.fetchDrives(points)
) emits.一旦源可观察对象(
this.fetchDrives(points)
)发出,我还使用switchMap
运算符来切换可观察对象。 Try the following尝试以下
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
}
);
Variable locations
will be of the form可变
locations
的形式为
// 'driveId': { lat: 12, lon: 54 }
{
'1': { lat: 12, lon: 54 },
'2': { lat: 12, lon: 54 },
'3': { lat: 12, lon: 54 }
}
To return an array of objects from forkJoin
you could send in an array of observables as the argument.要从
forkJoin
返回一个对象数组,您可以发送一个可观察对象数组作为参数。 For eg.例如。
forkJoin([obs1, obs2, ...])
. forkJoin([obs1, obs2, ...])
。 In the previous case we were sending an object as the argument ( forkJoin({'name1': obs1, 'name2': obs2, ...})
, so the output will also be an object.在前面的例子中,我们发送一个 object 作为参数(
forkJoin({'name1': obs1, 'name2': obs2, ...})
,所以 output 也将是一个 ZA8CFDE6331BD59EB26ACZF4 。
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
will be of the form locations
将采用以下形式
[
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 },
{ lat: 12, lon: 54 }
]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.