首页 > 解决方案 > 为什么订阅合并的 observable 的异步管道会覆盖先前发出的值?

问题描述

我有一个由两个可观察对象合并的可观察对象。我正在使用这个 observable 将它通过异步管道传递给子组件。当两个内部 observable 发射时,最后发射的值将被较新的值覆盖。

let a = new Subject();
let b = new Subject();
this.loaderData$ = merge(a.asObservable(), b.asObservable())
setTimeout(() => {
    b.next(2);
    a.next(1);
}, 1000)

let a = new Subject();
let b = new Subject();
this.loaderData$ = merge(a.asObservable(), b.asObservable())
setTimeout(() => {
    b.next(2);
    setTimeout(() => { a.next(1) }, 1000)
}, 1000)

html:

<ts-loader [loaderData]="loaderData$ | async"></ts-loader>

@Component({
  selector: 'ts-loader',
  templateUrl: './ts-loader.component.html',
  styleUrls: ['./ts-loader.component.scss']
})
export class TsLoaderComponent {

  @Input()
  set loaderData(loaderData:any){
    console.log(loaderData)
}

可观察的 loaderData$ 通过异步管道传递给子组件。但是第一段代码只输入 1 作为子组件,而第二段代码同时输入 1 和 2。

我无法弄清楚为什么这些 observables 会这样工作。

ps:我有一个解决方法来订阅子组件内部的 observable 并获得预期的结果。但我想让它与异步管道一起工作。

标签: angularrxjsreactive-programming

解决方案


它可能已经在您的异步管道中发生了,异步管道仅将最新结果呈现到屏幕上,因此您的 1 覆盖了 2。为了测试放置一个tap

let a = new Subject();
let b = new Subject();
this.loaderData$ = merge(a.asObservable(), b.asObservable()).pipe(tap(console.log))

setTimeout(() => {
    b.next(2);
    a.next(1);
}, 1000)

推荐阅读