英文:
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”会多次发出。通常情况下,这是不希望的。
我可以想到两种解决方法:
- 使用
debounceTime(0)
来抑制在同一事件循环中发生的发射:
combineLatest([
firstObs$,
firstObs$.pipe(map(({first, second}) => first + second)),
anotherObservable$,
])
.pipe(debounceTime(0));
- 只在
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:
- 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));
- only include each source once inside of
combineLatest
and usemap
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
- 将
firstObs$
的结果与observableSumOperation
映射在一起
const calculated$ = this.firstObs$.pipe(
mergeMap((values) =>
this.observableSumOperation(values.first, values.second).pipe(
map((sum) => ({ ...values, sum })),
),
),
)
- 将
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:
- Map the
firstObs$
result together withobservableSumOperation
const calculated$ = this.firstObs$.pipe(
mergeMap((values) =>
this.observableSumOperation(values.first, values.second).pipe(
map((sum) => ({ ...values, sum })),
),
),
)
- Combine
calculated$
withanotherObservable$
:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论