即使来源之一未发出值,RxJS combineLatest

god*_*rry 5 rxjs angular rxjs6

我需要来自两个来源的数据组合成一个res: {data1: any, data2: any}对象,即使其中一个来源不发出任何值,我也需要实现这一目标

这是我期望的结构:

xxx (
    source1,
    source2,
    (data1, data2) => ({data1: data1, data2: data2})
).subscribe(res => {
    doSomething1(res.data1)
    doSomething2(res.data2)
})
Run Code Online (Sandbox Code Playgroud)

有没有可以做到这一点的 rxjs 运营商?

目前我可以用的组合解决这个startWithcombineLatest-我发出空值,以便combineLatest可以开始发光值-没有更好的办法来解决这个不startWith(null)

combineLatest (
    source1.pipe(startWith(null)),
    source2.pipe(startWith(null)),
    (data1, data2) => ({data1: data1, data2: data2})
).subscribe(res => {
    if(res.data1) {
        doSomething1(res.data1)
    }
    if(res.data2) {
        doSomething2(res.data2)
    }
})
Run Code Online (Sandbox Code Playgroud)

kos*_*kos 6

正如@ritaj已经提到的,你似乎已经做得很好了:

\n\n
    \n
  1. 我会startWithdefaultIfEmpty 运算符替换,仅当任何可观察量为空时才继续。这是比较这两种方法的弹珠图:
  2. \n
\n\n

startWith 与 defaultIfEmpty 与 mergeLatest 运算符

\n\n

*请注意,带有发射两次的startWith

\n\n
    \n
  1. 使用唯一的对象(或符号)而不是简单的null,以防源流真正发出null。这将确保我们只过滤掉我们的标记,而不过滤掉真正的结果

  2. \n
  3. 使用过滤器而不是if-else在订阅 \xe2\x80\x94 中应该看起来更干净一些。.subscribe这是尽可能保持苗条的一般良好做法

  4. \n
\n\n

这是一个例子:

\n\n
const NO_VALUE = {};\n\nconst result$ = combineLatest(\n  a$.pipe(  defaultIfEmpty(NO_VALUE)  ),\n  b$.pipe(  defaultIfEmpty(NO_VALUE)  )\n)\n.pipe(filter(([a, b]) => a !== NO_VALUE || b !== NO_VALUE))\n
Run Code Online (Sandbox Code Playgroud)\n\n

^使用弹珠图运行此代码

\n\n

希望这可以帮助

\n


thi*_*nck 3

您可以使用BehaviorSubject。这为您提供了一个流,如果没有可用的最新值(在本例中为 null),该流在订阅时会发出默认值。

const subject1 = new BehaviorSubject(null),
      subject2 = new BehaviorSubject(null);

source1.subscribe(subject1);
source2.subscribe(subject2);

combineLatest(subject1, subject2).subscribe(res => {
    if(res.data1) {
        doSomething1(res.data1)
    }
    if(res.data2) {
        doSomething2(res.data2)
    }
});
Run Code Online (Sandbox Code Playgroud)