【问题标题】:Mapping an Array to another Array with an Inner Subscription使用内部订阅将数组映射到另一个数组
【发布时间】:2020-10-14 15:23:12
【问题描述】:

我有一个对象数组,我们会说它是关闭类型Objects[]

我需要将每个对象映射到另一种类型的对象,例如,DestinationObject[] 但是DestinationObject[] 上有一个属性,我需要在 Firebase 中查找,所以我需要订阅,或者 @ 987654324@.

不幸的是,如果我进行订阅,我会返回一个订阅,如果我执行pipe(map()),我会得到一个可观察对象列表,而不是可观察对象列表(即我想要Observable<Object[]> 而不是Observable<Object>[]

代码如下:

  processUsers(users: Users[], groupUsers: Users[]): Observable<MappedUser[]> {
    return groupUsers.map(groupUser => {
      return this.firebaseService.SubscribableFunction(groupUser.id).pipe(map(array => {
        return {
          name: groupUser.name,
          arrayLength: array.length,
        } as MappedUser;
      }));
    });
  }

所以两个简单的数组对象,我们确实返回了一个 MappedUser,但是由于 SubscribableFunction 上的 pipe(map()),它返回一个 Observable,因此第一行的映射返回一个 Observable 列表。这不是我想要的。

你有什么解决办法吗?我已经尝试过 map、mergeMap、from() of(),但它似乎没有按预期工作。

更新 这是请求的可订阅函数:

  SubscribableFunction(userId: string): Observable<Equipment[]> {
    const collection = this.afs.collection<Equipment>('equipment', ref => ref.where('userId', '==', userId));
    return collection.snapshotChanges().pipe(map(items => {
      return items.map(item => {
        return {
          id: item.payload.doc.id,
          ...item.payload.doc.data(),
        } as Equipment;
      });
    }));
  }

【问题讨论】:

    标签: angular rxjs


    【解决方案1】:

    你快到了。一旦你将源数组映射到一个可观察的数组,你会以[obs1, obs2, obs3, ...] 之类的东西结束。所以在这里你可以使用 RxJS forkJoin 函数来并行触发所有的 observables 并以对象数组的形式获取结果。

    试试下面的

    processUsers(users: Users[], groupUsers: Users[]): Observable<MappedUser[]> {
      return forkJoin(groupUsers.map(groupUser => { // <-- return `forkJoin` here
        return this.firebaseService.SubscribableFunction(groupUser.id).pipe(map(array => {
          return {
            name: groupUser.name,
            arrayLength: array.length,
          } as MappedUser;
        }));
      }));
    }
    

    现在您可以订阅该功能了

    processUsers(...).subscribe(
      res => console.log(res), // would log `[{MappedUser}, {MappedUser}, {MappedUser},... ],
      err => // good practice to handle HTTP errors
    );
    

    注意:RxJS forkJoin 只会在所有输入 observables 完成时发出。如果您希望获得来自 observable 的数据流,您可以查看 zipcombineLatest。你可以找到它们之间的区别here

    【讨论】:

    • 谢谢迈克尔。那似乎没有用。不知道发生了什么,但是进行一些登录,我看到地图中的每个 groupUser 都被处理了,然后来自 SubscribableFunction 的所有 observables 都得到了输出,但实际上我在 processUsers.subscribe() 上没有得到任何输出
    • @Simon:你有没有在错误回调中尝试console.log?即使有一个 observable 错误出现,observable 也不会发出。
    • 不幸的是没有错误。尝试将其转换为 Promises,但只需返回 Promises 列表。
    • 这没有意义。能否请您展示this.firebaseService.SubscribableFunction() 的实现?根据它的名称和性质,我假设它返回一个 observable。
    • 进一步阅读stackoverflow.com/questions/59137483/… stackoverflow.com/questions/40140149/… 可能会突出这个问题。他们说“像 map 或 forEach 这样的数组迭代器不适用于承诺,因为他们不知道如何等待结果。改用简单的 for 循环:”,我知道这是关于承诺,但我记得你不能明确从订阅返回一个值,因为它是异步的。可悲的是,我想我知道我现在需要做什么了。
    猜你喜欢
    • 2015-07-14
    • 2017-05-26
    • 2020-08-18
    • 2021-08-30
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多