如何组合 2 个或更多 observables 以便你知道哪个发出了?
How to combine 2 or more observables so that you know which emitted?
假设您有 2 个可观察对象:
const obs1$: Observable<string[]> = this.getObs1$();
const obs2$: Observable<string[]> = this.getObs2$();
我想结合这两个,以便在订阅(或 rxjs 映射)中我知道哪个发出了值。我不能使用 combineLatest,因为对于其他可观察对象,我只是得到它在某个时候发出的最新值。
似乎没有一个纯粹的 RxJS 解决方案(但希望有人能证明我是错的!)
作为解决方法,您可以在外部作用域中使用变量来跟踪发射的可观察对象
let trigger: TriggerEnum;
const obs1$: Observable<string[]> = this.getObs1$()
.pipe(tap(() => trigger = TriggerEnum.One));
const obs2$: Observable<string[]> = this.getObs2$()
.pipe(tap(() => trigger = TriggerEnum.Two));;
combineLatest(....).subscribe(
// check trigger value
);
来自文档 just-in-case:请注意,在每个可观察对象至少发出一个值之前,combineLatest 不会发出初始值
您可以使用 merge
将两个 observable 合并为一个 observable。然后,按照@martin 的建议进行操作,并将每个源的排放映射到一个允许您识别源的小结构:
const obs1$: Observable<number[]> = getNumbers();
const obs2$: Observable<string[]> = getLetters();
const combined$ = merge(
obs1$.pipe(map(data => ({ source: 'obs1$', data }))),
obs2$.pipe(map(data => ({ source: 'obs2$', data })))
);
combined$.subscribe(
({ source, data }) => console.log(`[${source}] data: ${data}`)
);
// OUTPUT:
//
// [obs1$] data: 1
// [obs2$] data: A
// [obs2$] data: A,B
// [obs2$] data: A,B,C
// [obs1$] data: 1,2
// [obs2$] data: A,B,C,D
...
这里有一个 StackBlitz 的小例子。
假设您有 2 个可观察对象:
const obs1$: Observable<string[]> = this.getObs1$();
const obs2$: Observable<string[]> = this.getObs2$();
我想结合这两个,以便在订阅(或 rxjs 映射)中我知道哪个发出了值。我不能使用 combineLatest,因为对于其他可观察对象,我只是得到它在某个时候发出的最新值。
似乎没有一个纯粹的 RxJS 解决方案(但希望有人能证明我是错的!)
作为解决方法,您可以在外部作用域中使用变量来跟踪发射的可观察对象
let trigger: TriggerEnum;
const obs1$: Observable<string[]> = this.getObs1$()
.pipe(tap(() => trigger = TriggerEnum.One));
const obs2$: Observable<string[]> = this.getObs2$()
.pipe(tap(() => trigger = TriggerEnum.Two));;
combineLatest(....).subscribe(
// check trigger value
);
来自文档 just-in-case:请注意,在每个可观察对象至少发出一个值之前,combineLatest 不会发出初始值
您可以使用 merge
将两个 observable 合并为一个 observable。然后,按照@martin 的建议进行操作,并将每个源的排放映射到一个允许您识别源的小结构:
const obs1$: Observable<number[]> = getNumbers();
const obs2$: Observable<string[]> = getLetters();
const combined$ = merge(
obs1$.pipe(map(data => ({ source: 'obs1$', data }))),
obs2$.pipe(map(data => ({ source: 'obs2$', data })))
);
combined$.subscribe(
({ source, data }) => console.log(`[${source}] data: ${data}`)
);
// OUTPUT:
//
// [obs1$] data: 1
// [obs2$] data: A
// [obs2$] data: A,B
// [obs2$] data: A,B,C
// [obs1$] data: 1,2
// [obs2$] data: A,B,C,D
...
这里有一个 StackBlitz 的小例子。