combineLatest 不发出最新值
combineLatest doesn't emit latest value
我很难理解为什么 combineLatest
没有返回最新值。这个例子有点做作,但至少它说明了我的问题。当 subject.value
正确时,请注意来自 combineLatest
可观察值 returns 的 color
的值是前一个值。就像 color$
observable 还没有发出。
import { map, distinctUntilChanged, combineLatest } from 'rxjs/operators'
import { Observable } from 'rxjs/observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const main$ = new BehaviorSubject({color: 'red'});
const color$ = main$.pipe(
map(state => state.color),
)
main$.pipe(
combineLatest(color$)
)
.subscribe(([state, color]) => {
console.log(state, color, main$.value.color);
})
main$.next({
color: 'yellow'
});
实际输出
{color: "red"} "red" "red"
{color: "yellow"} "red" "yellow"
{color: "yellow"} "yellow" "yellow"
预期输出
{color: "red"} "red" "red"
{color: "yellow"} "yellow" "yellow" // Notice middle value is yellow
{color: "yellow"} "yellow" "yellow"
https://stackblitz.com/edit/combine-latest-issue
如果有人可以帮助解释发生了什么,并在 rxjs
中提供解决方法或正确的思考方式,我将不胜感激。
第一个 main$
被更新,它作为更改馈入 combineLatest()
但不会触发输出,因为 color$
尚未发出值。然后 color$
计算它的新值,发出它,现在有两个值可用于 combineLatest()
并且输出第一行文本。
然后 main$
更新为 {color: "yellow"}
,输入 combineLatest()
,它从 main$
中获取最新值,从 color$
中获取最新值(仍然是 "red"
,并触发 {color: "yellow"} "red" "yellow"
.
的新输出
最后,color$
被更新并触发 combineLatest()
发出最后一行输出。
可视化正在发生的事情而不是文字可能更有用:
main$ R--------------------Y------------------------------
color$ -------R-----------------------Y---------------------
output -----[R,R]---------[Y,R]-----[Y,Y]------------------
如果您使用 zip
而不是 combineLatest
,您将更接近您的期望。看看下面如果你使用 zip
:
会发生什么
main$ R--------------------Y------------------------------
color$ -------R-----------------------Y---------------------
output -----[R,R]-------------------[Y,Y]------------------
使用 Observable.zip 而不是 combineLatest,它会发出与主题非常接近的值。它按预期对我有效。
我很难理解为什么 combineLatest
没有返回最新值。这个例子有点做作,但至少它说明了我的问题。当 subject.value
正确时,请注意来自 combineLatest
可观察值 returns 的 color
的值是前一个值。就像 color$
observable 还没有发出。
import { map, distinctUntilChanged, combineLatest } from 'rxjs/operators'
import { Observable } from 'rxjs/observable';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
const main$ = new BehaviorSubject({color: 'red'});
const color$ = main$.pipe(
map(state => state.color),
)
main$.pipe(
combineLatest(color$)
)
.subscribe(([state, color]) => {
console.log(state, color, main$.value.color);
})
main$.next({
color: 'yellow'
});
实际输出
{color: "red"} "red" "red"
{color: "yellow"} "red" "yellow"
{color: "yellow"} "yellow" "yellow"
预期输出
{color: "red"} "red" "red"
{color: "yellow"} "yellow" "yellow" // Notice middle value is yellow
{color: "yellow"} "yellow" "yellow"
https://stackblitz.com/edit/combine-latest-issue
如果有人可以帮助解释发生了什么,并在 rxjs
中提供解决方法或正确的思考方式,我将不胜感激。
第一个 main$
被更新,它作为更改馈入 combineLatest()
但不会触发输出,因为 color$
尚未发出值。然后 color$
计算它的新值,发出它,现在有两个值可用于 combineLatest()
并且输出第一行文本。
然后 main$
更新为 {color: "yellow"}
,输入 combineLatest()
,它从 main$
中获取最新值,从 color$
中获取最新值(仍然是 "red"
,并触发 {color: "yellow"} "red" "yellow"
.
最后,color$
被更新并触发 combineLatest()
发出最后一行输出。
可视化正在发生的事情而不是文字可能更有用:
main$ R--------------------Y------------------------------
color$ -------R-----------------------Y---------------------
output -----[R,R]---------[Y,R]-----[Y,Y]------------------
如果您使用 zip
而不是 combineLatest
,您将更接近您的期望。看看下面如果你使用 zip
:
main$ R--------------------Y------------------------------
color$ -------R-----------------------Y---------------------
output -----[R,R]-------------------[Y,Y]------------------
使用 Observable.zip 而不是 combineLatest,它会发出与主题非常接近的值。它按预期对我有效。