【问题标题】:Grouping two different observables of two different classes rxjs将两个不同类 rxjs 的两个不同 observable 分组
【发布时间】:2018-10-18 09:49:14
【问题描述】:

我有两个 Observables 发射 2 个不同类的数据:

1.用户类:

{
"id"=>25,
"username"=>"Chris",
.. other data 
}

2.UserWebsocket类

 {
     "user_id"=>25,
     "age"=>25,
      .. other data 
  }

我想通过 user_id 或 id 属性合并和分组这两个 observables。这样合并和分组类型的结果是:

[User|undefined,UserWebsocket|undefined]

为了更好地说明问题,我做了一个简单的大理石图:

这是怎么发生的?

【问题讨论】:

  • 看起来你可以使用combineLatest。也许在每个源 Observable 前使用 startWith(undefined)
  • @martin combineLatest 不会按 user_id 或 id 分组的问题。
  • 那么你想得到什么输出?
  • @martin 用户和 UserWebsocket 组合数组。但是 User 和 UserWebsocket 应该基于 user_id 和 id 组合。 User.id == UserWebsocket.user_id。否则将未组合的对象与 undefined 配对。

标签: javascript typescript rxjs


【解决方案1】:

正如马丁的评论所建议的那样,使用 combineLatest 并为每个部分设置一个起始值。假设你有 myUser$myUserWebsocket$ observables,你可以使用下面的代码来组合它们。首先添加一个起始值并将可观察值存储在新值中。将它们与combineLatest 结合使用。你必须订阅 uncold combined$ observable。

更新

另一种方法是使用merge 并将其与withLatestFrom 结合使用。

// Using RxJS v6+
import { merge } from 'rxjs';
import { startWith, map, withLatestFrom } from 'rxjs/operators';

// Your allready defined observables named e.g. myUser$ and myUserWebsocket$
// Add a starting value, since if user fires, websocket has no value yet.
const user$ = myUser$.pipe(
  startWith(undefined)
)
const userWebsocket$ = myUserWebsocket$.pipe(
  startWith(undefined)
)

const combined$ = merge(
  user$,
  userWebsocket$
).pipe(
  withLatestFrom(user$),
  withLatestFrom(userWebsocket$),
  map(([[merge, latestUser], latestWebsocket]) => {
    if (merge.user_id) { // merge is typeof userWebsocket, make sure user does not have user_id property
      if (latestUser && merge.user_id === latestUser.id) {
        return [latestUser, merge];
      } else {
        return [undefined, merge];
      }
    } else if (merge.id && !merge.user_id) { // merge is typeof user
      if (latestWebsocket && merge.id === latestWebsocket.user_id) {
        return [merge, latestWebsocket];
      } else {
        return [merge, undefined];
      }
    }
  })
);

combined$.subscribe([user, websocket] => {
  console.log(user, websocket);
});

【讨论】:

  • 感谢您的回答。我担心 combineLatest 如何通过 user_id 或 id 属性对它们进行分组。因为 combineLatest 可能会在不关心 user_id 和 id 是否相等的情况下组合它们。我的要求是如果 user_id == id (参见第二个结果) 将它们组合起来,否则不将对象与未定义的对应对象组合起来(参见第一个和最后一个结果)
  • 编辑了我的答案。看看吧。
猜你喜欢
  • 1970-01-01
  • 2021-06-04
  • 2023-03-13
  • 2021-05-20
  • 1970-01-01
  • 2020-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多