【问题标题】:Merge two observables, single output合并两个 observables,单个输出
【发布时间】:2021-03-15 04:57:56
【问题描述】:

大家好,我正在尝试掌握 RxJS 库和反应式编程的整个理念。 我正在尝试将两个可观察对象合并为一个。第一个 observable 包含一个对象数组DefectImages[],第二个 observable 包含一个字符串数组,然后我将其转换为一个DefectImages[] 数组。之后,我想将这两个 observables 合并为一个。

在我的代码下面:

const observable = CachedPhotosBuffer.getInstance().asObservable()
      .pipe(
        switchMap(data => {
          return data.map((url) => DefectImage.createTempImage(url, 'you', Date.now()));
        })
        );
    this.observable = Observable.create(observer => observer.next(this.defectImages));
    this.observable.pipe(
      merge(observable)
    ).subscribe(data => console.log('merge', data))

这种工作如我所料,但这个合并的 observables 连接到 HTML Angular 模板。

<ion-list>
    **<ng-container *ngFor="let image of observable | async">**
      <ion-item *ngIf="image.deletedAt === undefined">
        <span class="item-container" (click)="showImage(image)">
          <ion-thumbnail item-start>
            <img id="{{image.url}}" src="{{getUrl(image) + image.url}}">
          </ion-thumbnail>
          <span>
            <p>created at: {{image.createdAt | date: 'd/M/yy H:m'}}</p>
            <p>created by: {{image.createdBy}}</p>
          </span>
        </span>
        <button ion-button item-end (click)="removeImage(image)">
          <ion-icon name="trash"></ion-icon>
        </button>
      </ion-item>
    </ng-container>
  </ion-list>

我得到的控制台日志:

我的问题是为什么每个流都有两个单独的日志,而不是一个包含所有数据的控制台日志?

【问题讨论】:

    标签: javascript angular rxjs reactive-programming


    【解决方案1】:

    合并可观察对象意味着两个可观察对象发出的项目将由新合并的可观察对象连续和单独发出,参见this page。如果您的可观察对象每个只发出一个项目,并且您希望通过连接数组来合并 项目,则可以使用zip operator,如下所示:

    zip(observable, this.observable)
      .pipe(map(x => x[0].concat(x[1])))
      .subscribe(data => console.log('merge', data))
    

    更准确地说,zip(obsa, obsb) 创建了一个新的 observable,它侦听 obsa 和 obsb,并在从 obsa 接收 itema 和从 obsb 接收 item 之后发出 item x=[itema, itemb]。在您的情况下,x[0]=itemax[1]=itemb 是数组,(x =&gt; x[0].concat(x[1])) 连接这两个数组。请注意,如果 obsa 和 obsb 发出多个数组,则压缩后的 observable 将始终等待从 obsa 获得一项,从 obsb 获得一项,然后再发出新的[itema, itemb]。对于 concat() 方法,请参见 this page

    别忘了import { zip } from 'rxjs'import { map } from 'rxjs/operators'

    【讨论】:

    • 就像一个魅力,你能解释一下为什么我们需要地图操作员吗?我们在地图之前和地图之后有什么?为什么以这种方式实现 x[0].concat(x[1])??
    • 您可以使用x.flat() 而不是x[o].concat(x[1])。它更简洁并且已经得到广泛支持:caniuse.com/array-flat
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多