Combine Latest – 相同的可观察对象返回不同的值

huangapple go评论65阅读模式
英文:

Combine Latest - same observable returning different values

问题

如何在同一个可观察对象中返回不同的值,而不需要多次调用?我打算只订阅一次 firstObs$,但要返回值和 sumFromValues。

combineLatest([
    this.firstObs$,
    this.firstObs$.pipe(
        switchMap(someOperation => {
            return this.observableSumOperation(someOperation.first, someOperation.second);
        })
    ),
    this.anotherObservable$,
])
.subscribe(([values, sumFromValues, anotherValues]) => {
    // 在这里处理返回的值
});
英文:

How to return different values from the same observable without multiple calls? I intend to subscribe just one time the firstObs$, but return the values and sumFromValues.

combineLatest([
            this.firstObs$,
            this.firstObs$.pipe(
                switchMap(someOperation => {
                       return this.observableSumOperation(someOperation.first, someOperation.second)
                })
            ),
          
            this.anotherObservable$,
        ])
          .subscribe(([values, sumFromValues, anotherValues]) => {
            }

答案1

得分: 0

如您所注意到的,当您在combineLatest中包含相同的源可观察对象时,“combinelatest observable”会多次发出。通常情况下,这是不希望的。

我可以想到两种解决方法:

  1. 使用debounceTime(0)来抑制在同一事件循环中发生的发射:
combineLatest([
  firstObs$,
  firstObs$.pipe(map(({first, second}) => first + second)),
  anotherObservable$,
])
.pipe(debounceTime(0));
  1. 只在combineLatest中包含每个源一次,并使用map构建一个包含派生值的新数组/对象:
combineLatest([
  firstObs$,
  anotherObservable$,
])
.pipe(
  map(([values, anotherValues]) => [
    values,
    values.first + values.second,
    anotherValues
  ])
);

这里是一个展示问题和解决方案的StackBlitz链接

英文:

As you've noticed, when you include the same source observable inside of combineLatest, the "combinelatest observable" will emit multiple times. Generally this is not desirable.

I can think of two solutions for this:

  1. use debounceTime(0) to suppress emissions that occur in the same event loop:
combineLatest([
  firstObs$,
  firstObs$.pipe(map(({first, second}) => first + second)),
  anotherObservable$,
])
.pipe(debounceTime(0));
  1. only include each source once inside of combineLatest and use map to build a new array/object that includes your derived value:
combineLatest([
  firstObs$,
  anotherObservable$,
])
.pipe(
  map(([values, anotherValues]) => [
    values,
    values.first + values.second,
    anotherValues
  ])
);

Here is a StackBlitz that shows the problem and solutions.

答案2

得分: 0

  1. firstObs$的结果与observableSumOperation映射在一起
const calculated$ = this.firstObs$.pipe(
      mergeMap((values) =>
        this.observableSumOperation(values.first, values.second).pipe(
          map((sum) => ({ ...values, sum })),
        ),
      ),
    )
  1. calculated$anotherObservable$组合:
combineLatest([calculated$, this.anotherObservable$]).subscribe(
      ([values, anotherValues]) => {
        const { first, second, sum } = values
      },
    )

请注意,combineLatest仅在每个可观察对象至少发出一次时才会触发。因此,如果anotherObservable$没有发出值,您将不会进入订阅方法。

英文:

Since you didn't specify what anotherObservable contains and how it behaves its hard to say how to best combine the values. But one idea is to split the combination of observables into two steps:

  1. Map the firstObs$ result together with observableSumOperation
const calculated$ = this.firstObs$.pipe(
      mergeMap((values) =>
        this.observableSumOperation(values.first, values.second).pipe(
          map((sum) => ({ ...values, sum })),
        ),
      ),
    )
  1. Combine calculated$with anotherObservable$:
 combineLatest([calculated$, this.anotherObservable$]).subscribe(
      ([values, anotherValues]) => {
        const { first, second, sum } = values
      },
    )

Note that combineLatest will only fire as soon as every observable emits at least once. So if anotherObservable$ does not emit a value, you will not enter the subscribe method

huangapple
  • 本文由 发表于 2023年6月5日 16:58:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76404875.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定