javascript 合并两个 observables,单个输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53419090/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:11:21  来源:igfitidea点击:

Merge two observables, single output

javascriptangularrxjsreactive-programming

提问by filemonczyk

Hello guys Im trying to grasp RxJS lib and the whole idea of reactive programming. Im trying to merge two observables into one. First observable contains array of objects DefectImages[]the second observable contains array of strings, which then I convert to array of DefectImages[]. After that I would like to merge these two observables into one.

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

Below my code:

在我的代码下面:

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))

This KIND OF works as I expect BUT this merged observables Is connected to html angular template.

这种类型的工作正如我所期望的,但是这个合并的 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>

This is the console logs Im getting enter image description here

这是我得到的控制台日志 在此处输入图片说明

My question is Why do I have two separate logs for each stream instead of One console log with all the data combined?

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

回答by Rolvernew

Merging observables means that items emitted by both observable will be emitted successively and separately by the new merged observable, cf this page. If your observables emit just one item each and you want the merge the itemsby concatenating the arrays, you could use the zip operatoras follows:

合并 observables 意味着由两个 observable 发出的项目将被新合并的 observable 连续和单独发出,参见本页。如果您的 observable 每个只发出一个项目,并且您希望通过连接数组来合并项目,您可以使用zip 运算符,如下所示:

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

More precisely zip(obsa, obsb)creates a new observable that listens to obsa and obsb, and after receiving itema from obsa and itemb from obsb emits the item x=[itema, itemb]. In your case x[0]=itema, x[1]=itembare arrays and (x => x[0].concat(x[1]))concatenates these two arrays. Note that if obsa and obsb emit more than one array, the zipped observable will always wait to have one item from obsa and one from obsb before emitting a new [itema, itemb]. For the concat() method, cf this page.

更准确地说,zip(obsa, obsb)创建一个新的 observable 来监听 obsa 和 obsb,并在从 obsa 接收到 itema 和从 obsb 接收到 item 后发出 item x=[itema, itemb]。在您的情况下x[0]=itemax[1]=itemb是数组并(x => x[0].concat(x[1]))连接这两个数组。请注意,如果 obsa 和 obsb 发出多个数组,则压缩后的 observable 将在发出新的[itema, itemb]. 对于 concat() 方法,请参阅此页面

And don't forget to import { zip } from 'rxjs'and import { map } from 'rxjs/operators'.

并且不要忘记import { zip } from 'rxjs'import { map } from 'rxjs/operators'