循环数组时Angular RxJs升高 [英] Angular RxJs level up during looping an array
问题描述
我有一个http get请求,以获取类似的数组
I have an http get request to get an array like
[
{name: 'name1', id: 1, specialProp: [] },
{name: 'name2', id: 2, specialProp: [] }
]
我需要获取每个数组项,获取一个ID,然后向服务器发送请求以获取一些信息.结果应写入属性 specialProp
中.之后,我需要获取道具 specialProp
的数组,并为每个项目获取一些数据,然后将其放入 anotherSpecialProp
中.最后,我应该拥有
I need to get each of array items, take an id and send a request to server to get some information. The results should be written into the property specialProp
. After that I need to take the array of the prop specialProp
and for each item get some data, put it into anotherSpecialProp
. In the end I should have the final array like
[
{name: 'name1', id: 1, specialProp: [
{name: 'c', anotherSpecialProp: []},
{name: 'd', anotherSpecialProp: []}
]},
{name: 'name2', id: 2, specialProp: [
{name: 'a', anotherSpecialProp: []},
{name: 'b', anotherSpecialProp: []}
]}
]
我有代码:
this.http.get(url)
.pipe(
switchMap((mainItemArr: any) => from(mainItemArr)),
mergeMap((mainItem: any): any => {
return this.getSomeInfo(mainItem.Id) //another http get request
.pipe(
map((data: any): any => {
return Object.assign(mainItem, { specialProp: data })
}),
switchMap((mainItemArr: any): any => from(mainItemArr.specialProp)),
concatMap((item: any): any => {
return this.getSomeOtherInfo(item.Id) // one more http get request
.pipe(
map((data: any): any => Object.assign({}, task, { anotherSpecialProp: data }))
)
}),
)
})
)
因此在订阅中,我只收到项目,而不是整个mainItemArr.有人可以帮我解决这个问题吗?:)
So in subscribe I receive just the items, not the whole mainItemArr. Could anyone please assist me with the issue?:)
推荐答案
主要技巧是使用 map
将合并范围的属性与请求结果合并.
The main trick is to use map
to merge scoped property with request result.
下面是一个粗略的示例,说明如何在第一级( specialProp
)实现该目标:
Here's a rough example how to achieve this for the first level (specialProp
):
this.http.get(url).pipe(
mergeMap(mainItemArr => {
// forkJoin will wait for each request to complete
return forkJoin(
// make a subsequent request for each item in mainItemArr
mainItemArr.map(mainItem => {
return this.getSomeInfo(mainItem.Id).pipe(
// merge getSomeInfo result with the mainItem
map(someInfo => {
return {
...mainItem,
specialProp: someInfo
};
})
)
})
)
})
)
对于 anotherSpecialProp
请求-您需要更深入一层.
For the anotherSpecialProp
requests — you'll need to go one level deeper.
在现实世界中的应用程序中,我建议将这些后续调用分成单独的函数/方法.
In a real world application I'd suggest splitting those subsequent calls into separate functions/methods.
注意:
您不需要将数组变成可观察的:
You don't need turning array into Observable:
mergeMap(mainArray => mainArray)
相反,您可以将其保留在JS范围内,然后在 mergeMap
中进行后续请求,例如:
Instead you might keep it in the JS scope and do subsequent requests in the mergeMap
, e.g.:
mergeMap(mainArray => {
// making sub requests here
})
使用 mergeMap
将数组转换为Observable也应该可行,尽管在深入1级时可能会更加混乱,恕我直言.无论如何, map
是主要技巧.
Using mergeMap
to turn array into Observable should work too, though it might be more confusing when diving 1 level deeper, imho. Anyway, the map
does the main trick.
希望这会有所帮助
这篇关于循环数组时Angular RxJs升高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!