首页 > 解决方案 > [Rxjs]如何在Rxjs中对多个同步事件进行分组,只触发一次订阅者?

问题描述

我有菱形流依赖和单个事件转换为多个然后合并为一个,但触发多次。

我想将它们分组为单个输出。

我找到了一个解决方案,但我不确定这是正确的方法还是反模式。

如果我的解决方案可能很脏,那么推荐的方法是什么?

原来的

const obs1 = new Subject<number>();
const obs2 = obs1.pipe(map(v => v + 1));
const obs3 = obs1.pipe(map(v => v * 2));
const obs4 = combineLatest(obs1, obs2, obs3);
obs4.subscribe(console.log);

interval(2000)
    .pipe(take(3))
    .subscribe(obs1);

输出:

(3) [0, 1, 0]
(3) [1, 1, 0]
(3) [1, 2, 0]
(3) [1, 2, 2]
(3) [2, 2, 2]
(3) [2, 3, 2]
(3) [2, 3, 4]

我的解决方案

const obs1 = new Subject<number>();
const obs2 = obs1.pipe(map(v => v + 1));
const obs3 = obs1.pipe(map(v => v * 2));
const obs4 = combineLatest(obs1, obs2, obs3).pipe(
    switchMap(v => of(v, asapScheduler)),
);
obs4.subscribe(console.log);

interval(2000)
    .pipe(take(3))
    .subscribe(obs1);

输出(也预期):

(3) [0, 1, 0]
(3) [1, 2, 2]
(3) [2, 3, 4]

标签: rxjs

解决方案


如果您只是在转换输入值,为什么不做类似的事情

interval(2000)
    .pipe(
        take(3),
        map(val => ([val, val + 1, val * 2])),
    )
    .subscribe(array => console.log(array));

还是您的真实数据源不仅仅是转换?

或者,如果您需要所有三个来源并想要组合最新值,withLatestFrom这可能是一个不错的选择,这也会产生您预期的输出:

const obs1 = new Subject<number>();
const obs2 = obs1.pipe(map(v => v + 1));
const obs3 = obs1.pipe(map(v => v * 2));
const obs4 = obs1.pipe(
  withLatestFrom(obs2, obs3)
);
obs4.subscribe(console.log);

interval(2000)
    .pipe(take(3))
    .subscribe(obs1);

推荐阅读