Rxjs 我想使用rx.js合并多个数据源,并支持添加和删除数据源

Rxjs 我想使用rx.js合并多个数据源,并支持添加和删除数据源,rxjs,Rxjs,我有多个数据源,它们是可热观察的(行为主体) const data1$ = new BehaviorSubject({key: 'a', value: 1}) const data2$ = new BehaviorSubject({key: 'b', value: 2}) const data3$ = new BehaviorSubject({key: 'c', value: 3}) 我有一个根来聚合其他数据源 const root$ = new BehaviorSubject({ field

我有多个数据源,它们是可热观察的(行为主体)

const data1$ = new BehaviorSubject({key: 'a', value: 1})
const data2$ = new BehaviorSubject({key: 'b', value: 2})
const data3$ = new BehaviorSubject({key: 'c', value: 3})
我有一个根来聚合其他数据源

const root$ = new BehaviorSubject({ field: {/* Stores the values of other data sources*/ } })
其思想是,当我订阅root$时,我会得到他们数据的聚合,当dataX$更新时(下一步),我会得到更新的聚合

另外,我希望在添加/删除数据源时接收更新

到目前为止,这是我的代码,我想不出实现它的方法

const a1$ = new BehaviorSubject({key: 'a', value: 1})
const a2$ = new BehaviorSubject({key: 'b', value: 2})
const trunk$ = new BehaviorSubject([a1$, a2$])

function add(dataSourch) {
  trunk$.next([...trunk$.getValue(), dataSourch])
}
function remove(key) {
  const dataArr = trunk$.getValue()
  const newArr = dataArr.filter((sourch) => sourch.key !== key)
  trunk$.next([...newArr])
}
------------------------------------

目前:我的问题是在下面的代码中添加一个新的数据源,最终的数据源将触发多个更新

我添加了有关此问题的附加信息和代码

我有一些基础数据源,它们由不同的角色订阅,并由不同的角色修改。 同时,我有一个聚合数据源,它将基础数据源的数据聚合到一个字段(聚合数据源本身有其他数据), 并由一些角色订阅。 基础数据源管理模块支持数据源的新增和删除。


您可以通过使用操作符来实现此行为

const{BehaviorSubject,Subject,merge}=rxjs;
const{map,scan}=rxjs.operators;
//改变状态/数据聚合的函数
常量add=(数据)=>(状态)=>([…状态,数据]);
constdeleteall=()=>(state)=>([]);
const data1$=new BehaviorSubject({key:'a',value:1})
const data2$=new BehaviorSubject({key:'b',value:2})
const data3$=new BehaviorSubject({key:'c',value:3})
//表示所有add事件的可观察的
const add$=merge(数据1$、数据2$、数据3$)
//表示所有事件的可观察的
const deleteAll$=新主题();
常量数据$=合并(
//将第一个(外部)mutate函数应用于事件可观察对象
添加$.pipe(映射(添加)),
deleteAll$.pipe(映射(deleteAll))
).烟斗(
//应用第二个(内部)mutate函数以最终修改并返回更新的状态
扫描((状态,fn)=>fn(状态),[])
)
数据$.subscribe(console.log)
//进一步的事件示例
data1$.next({key:'d',value:4})
deleteAll$.next();
data1$.next({key:'e',value:5})

谢谢您的回答。这给我带来了一个解决办法。现在,我已经更新了我的问题和代码。在代码中,新数据源将触发四次更新。有没有办法只触发一次。我还能做些什么来改进我的代码呢?你可以一个接一个地问问题吗。你有一个特别的问题,答案很合适。如果出现新问题,请提出新问题。你能回到你以前的问题上来吗。如果你愿意,你可以在我的评论下发布你的新问题,我会看一看。还要记住,如果答案对你的问题有效,你就有机会对答案进行升级投票和/或给它一个绿色支票。因为它可能会回答你的问题(但当你问一个新问题时,你会得到一个详细的答案),你可以将下一个观察值转换为观察值。这样,您就可以将新的
dataN$
放入一个可观察的
data$
中,并在需要时将其“取消装箱”。谢谢您的回答。我想我现在知道怎么提问了。
const data1$ = new BehaviorSubject({key: 'a', value: 1})
const data2$ = new BehaviorSubject({key: 'b', value: 1})
const data3$ = new BehaviorSubject({key: 'c', value: 1})
const data4$ = new BehaviorSubject({key: 'd', value: 1})

const addSourch = (curr: any) => (prev: any) => ([curr, ...prev])
const addSourch$ = new Subject()
const deleteSourchByOb = (curr: any) => (arr: any) => {
  const newArr = arr.filter((ele: any) => ele !== curr)
  return newArr
} 
const deleteSourchByOb$ = new Subject()
const deleteAll = () => (prev: any) => ([])
const deleteAll$ = new Subject()

const sourch$ = new BehaviorSubject([data1$, data2$, data3$])


const root$ = merge(
  sourch$.pipe(map(arr => (curr: any) => [...arr, ...curr])),
  addSourch$.pipe(map(addSourch)),
  deleteSourchByOb$.pipe(map(deleteSourchByOb)),
  deleteAll$.pipe(map(deleteAll))
).pipe(
  scan((state, fn: Function) => fn(state), [])
) 

const thunk$ = new BehaviorSubject({ field: { }})

const root2$= root$.pipe(
  mergeMap(arr => merge(...arr)),
  map((v: any) => (curr: any) => {
    const obj = cloneDeep(curr)
    obj[v.key] = v
    return obj
  })
).pipe(
  scan((state, fn) => fn(state), {})
)

const final$ = combineLatest([root2$, thunk$]).pipe(
  map((arr) => {
    arr[1].field = arr[0]
    return arr[1]
  }) 
)
final$.subscribe(console.log)