【问题标题】:Rxjs Returns first result of two observables run sequentiallyRxjs 返回两个 observables 顺序运行的第一个结果
【发布时间】:2019-09-09 21:22:16
【问题描述】:

我需要按顺序运行两个可观察对象并仅返回第一个可观察对象的结果。第二个 observable 需要在运行前完成第一个。

我找到了解决方法,但我并不满意。你可以在这里测试它:plunker test

const first = Observable.of(10).delay(1000).do(res => console.log('first'));
const second = Observable.of(20).do(res => console.log('second'));
console.log('start');
const test = first.concatMap(ev => second.map(x=> ev)).subscribe(res => 
console.log(res));

我认为(我希望!)存在更好的解决方案,但我找不到。 提前感谢您的帮助。

【问题讨论】:

  • 我认为没有比这更好的方法了。唯一的改进可能是使用ev => second.mapTo(ev) 使其更加明显。

标签: angular rxjs observable sequential


【解决方案1】:

我在脑海中将flatMap 内部翻译为then,所以我希望看到类似...

const first = Observable.of(10).delay(1000).do(res => console.log('first'));
const second = Observable.of(20).do(res => console.log('second'));
const test = first.flatMap(rsp => { return second.mapTo(rsp); });

这与您发布的内容并没有什么不同,但直觉上对我来说更有意义,因为我不会开始考虑 concat 操作。

更新:

我想你也可以这样做......

const test = first.delayWhen(() => second.mapTo(0));

...但我不确定这是否更具可读性。

【讨论】:

  • 这两个条目有效,但我想要比second.mapTo更干净的东西@
  • 您总是可以编写自己的运算符或静态函数。称它为 bufferUntil 或 delayUntil 什么的。
【解决方案2】:

我不确定,但我认为您可以使用 concatMapTo。请参见示例 2。 在你的情况下:

const first$ = of(10).pipe(delay(1000),tap(res => console.log('first')));
const second$ = of(20).pipe(tap(res => console.log('second')));

const test = first$.pipe(
  concatMapTo(
    second$,
    (first, second) => first
  )
);
test.subscribe(res => console.log(res));

https://stackblitz.com/edit/typescript-xrmsy5

如果你想管理更多的 observable,你可以使用 switchMap/mergeMap。例如

const test = first$.pipe(
  // map(e => { if(e === '1') throw e; return e; } ), //throwing invalid result
  switchMap(e => second$, (f,s) => {console.log('switchMap',f,s); return f;}),
  switchMap(e => trird$, (f,s) => {console.log('switchMap', f,s); return f;}),
);

https://stackblitz.com/edit/typescript-mnsd8a

【讨论】:

    【解决方案3】:

    用户mergetake(1)

    Observable.merge(first, second).take(1).subscribe(x=>console.log(x));
    

    【讨论】:

    • 它只返回第二个结果。这不是我想要的
    【解决方案4】:
    const test = first
        .pipe(
            delayWhen(() => second)
        )
        .subscribe(() => {
            ...
        });
    

    这应该按顺序执行第一个和第二个可观察对象,但仅在第二个可观察对象的结果在内部发出后才发出第一个可观察对象的结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-22
      • 1970-01-01
      • 2018-08-29
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多