首页 > 解决方案 > 用于可观察链接的仓促 forkjoin 替代 rxjs?

问题描述

我有 5 个不同的 API 调用要进行,它们现在都链接在 forkJoin 中。我的新要求是订阅应该在任何新的 observable 解决时触发。

rxjs 中是否有任何运算符或任何其他技巧可以让我保持链接,但是每次任何可观察到的解决方案都应该触发它?

forkJoin(
        this.myService.api1(),
        this.myService.api2(),
        this.myService.api3(),
        this.myService.api4(),
        this.myService.api5()
    )
        .subscribe(
            ([r1,r2,r3,r4,r5]) => { ... do something })

标签: angularrxjsrxjs5

解决方案


您可以使用combineLatest从每个可观察源发出最新值。在每个源 observable 至少发出一次之前它不会发出,因此您可以使用它startWith来提供起始值:

combineLatest(
        this.myService.api1().pipe(startWith(null)),
        this.myService.api2().pipe(startWith(null)),
        this.myService.api3().pipe(startWith(null)),
        this.myService.api4().pipe(startWith(null)),
        this.myService.api5().pipe(startWith(null))
    )
        .subscribe(
            ([r1,r2,r3,r4,r5]) => { ... do something })

初始输出将是[null, null, null, null, null]. 当每个 observable 发出时,它将替换null数组中的相应值。

如果要忽略初始发射,可以使用skip(1).

const sourceOne = of('Hello').pipe(delay(1000));
const sourceTwo = of('World!').pipe(delay(2000));
const sourceThree = of('Goodbye').pipe(delay(3000));
const sourceFour = of('World!').pipe(delay(4000));

//wait until all observables have emitted a value then emit all as an array
const example = combineLatest(
  sourceOne.pipe(startWith(null)),
  sourceTwo.pipe(startWith(null)),
  sourceThree.pipe(startWith(null)),
  sourceFour.pipe(startWith(null))
)
.pipe(skip(1));

//output:
//["Hello", null, null, null]
//["Hello", "World!", null null]
//["Hello", "World!", "Goodbye", null]
//["Hello", "World!", "Goodbye", "World!"]
//Complete
const subscribe = example.subscribe(val => console.log(val), null, () => console.log('Complete'));

这里有一个StackBlitz来试一试。


推荐阅读