循环数组时Angular RxJs升高 [英] Angular RxJs level up during looping an array

查看:89
本文介绍了循环数组时Angular RxJs升高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆