资讯专栏INFORMATION COLUMN

RxJS: 详解forkJoin, zip, combineLatest之间的区别

Mr_houzi / 1357人阅读

摘要:信号会由于发射源的不同发射到多次而和仅会发射其中一个,且只发射一次,标志着流的结束。以此类推直到其中某个流发出结束信号,整个被合并后的流结束,不再发射数据。

前言

forkJoin, zip, combineLatestrxjs中的合并操作符,用于对多个流进行合并。很多人第一次接触rxjs时往往分不清它们之间的区别,其实这很正常,因为当你准备用来合并的流是那种只会发射一次数据就关闭的流时(比如http请求),就结果而言这三个操作符没有任何区别。

const ob1 = Rx.Observable.of(1).delay(1000);
const ob2 = Rx.Observable.of(2).delay(2000);
const ob3 = Rx.Observable.of(3).delay(3000);

Rx.Observable.forkJoin(ob1, ob2, ob3).subscribe((data) => console.log(data));
Rx.Observable.zip(ob1, ob2, ob3).subscribe((data) => console.log(data));
Rx.Observable.combineLatest(ob1, ob2, ob3).subscribe((data) => console.log(data));

// [1, 2, 3]
// [1, 2, 3]
// [1, 2, 3]
// 都是在3秒的时候打印

rxjs中很多操作符功能相近,只有当其操作的流会多次发射数据时才会体现出它们之间的区别,下面我们来详细解释forkJoin, zip, 和combineLatest

一个基本概念

首先我们要知道,一个流(或者说Observable序列)的生命周期中,每次发射数据会发出next信号(Notification),结束发射时会发出complete信号,发生错误时发出error信号,三个信号分别对应observer的三个方法。next信号会由于发射源的不同发射0到多次;而completeerror仅会发射其中一个,且只发射一次,标志着流的结束。
subscribe接收一个observer对象用来处理上述三种信号,只传入一个函数会被认为是next方法,因此传入subscribenext方法会执行0到N次,N为序列正常发射信号的次数。

forkJoin

forkJoin合并的流,会在每个被合并的流都发出结束信号时发射一次也是唯一一次数据。假设我们有两个流:

const ob1 = Rx.Observable.interval(1000).map(d => `ob1:${d}`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:${d}`).take(2);

Rx.Observable.forkJoin(ob1, ob2).subscribe((data) => console.log(data));
// ["ob1:2", "ob2:1"]

ob1会在发射完第三个数据时停止发射,ob2会在发射完第二个数据时停止,而forkJoin合并后的流会等到ob1ob2都结束时,发射一次数据,也就是触发一次subscribe里的回调,接收到的数据为ob1ob2发射的最后一次数据的数组。

zip

zip工作原理如下,当每个传入zip的流都发射完毕第一次数据时,zip将这些数据合并为数组并发射出去;当这些流都发射完第二次数据时,zip再次将它们合并为数组并发射。以此类推直到其中某个流发出结束信号,整个被合并后的流结束,不再发射数据。

const ob1 = Rx.Observable.interval(1000).map(d => `ob1:${d}`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:${d}`).take(2);

Rx.Observable.zip(ob1, ob2).subscribe({
  next: (data) => console.log(data),
  complete: () => console.log("complete")
});
// ["ob1:0", "ob2:0"] ob1等待ob2发射数据,之后合并
// ["ob1:1", "ob2:1"] 此时ob2结束,整个合并的流也结束
// "complete"

zipforkJoin的区别在于,forkJoin仅会合并各个子流最后发射的一次数据,触发一次回调;zip会等待每个子流都发射完一次数据然后合并发射,之后继续等待,直到其中某个流结束(因为此时不能使合并的数据包含每个子流的数据)。

combineLatest

combineLatestzip很相似,combineLatest一开始也会等待每个子流都发射完一次数据,但是在合并时,如果子流1在等待其他流发射数据期间又发射了新数据,则使用子流最新发射的数据进行合并,之后每当有某个流发射新数据,不再等待其他流同步发射数据,而是使用其他流之前的最近一次数据进行合并。

const ob1 = Rx.Observable.interval(1000).map(d => `ob1:${d}`).take(3);
const ob2 = Rx.Observable.interval(2000).map(d => `ob2:${d}`).take(2);

Rx.Observable.combineLatest(ob1, ob2).subscribe({
  next: (data) => console.log(data),
  complete: () => console.log("complete")
});
// ["ob1:1", "ob2:0"] ob1等待ob2发射,当ob2发射时ob1已经发射了第二次数据,使用ob1的第二次数据
// ["ob1:2", "ob2:0"] ob1继续发射第三次也是最后一次数据,ob2虽然还未发射,但是可以使用它上一次的数据
// ["ob1:2", "ob2:1"] ob2发射第二次也是最后一次数据,使ob1上一次的数据。
// "complete"

本期内容结束,下一期会继续带来rxjs的其他操作符或者概念详解。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/92383.html

相关文章

  • [译]RxJS文档08——操作符分类

    摘要:原文各种各样的操作符按照不同的目的,分类几个大类创建,变化,过滤,组合,广播,错误处理,使用工具等等。 原文:http://reactivex.io/rxjs/manu... 各种各样的操作符按照不同的目的,分类几个大类:创建,变化,过滤,组合,广播(multicasting),错误处理,使用工具等等。 以下的列表,按照分类罗列了全部的操作符: 创建操作符 Creation Opera...

    phoenixsky 评论0 收藏0
  • RxJS 6有哪些新变化?

    摘要:有哪些新变化于年月日正式发布,为开发人员带来了一些令人兴奋的增补和改进。不要移除包,直到你将所有的链式操作修改为管道操作符。 RxJS 6有哪些新变化? RxJs 6于2018年4月24日正式发布,为开发人员带来了一些令人兴奋的增补和改进。Ben Lesh, rxJS核心开发成员,强调: RxJS 6在拥有更小API的同时,带来了更整洁的引入方式 提供一个npm包,该package可...

    LeanCloud 评论0 收藏0
  • 从命令式到响应式(五)

    摘要:输出流只有在所有的输入流都完成以后才能完成,任何一条输入流上的错误都将立即推送到输出流上。如果没有转入输入流,输出流将会立即发出结束通知。返回值以数组形式获取到的每一个输入流的值,或者来自映射函数的值。返回值仅从最新的内部流上取值的流。 接着上一节的操作符继续,让我们直奔主题。 组合类操作符 组合类的操作符可以将不同流数据按一定的规则进行合并,从而获得所需要的完整数据。 combine...

    CoderBear 评论0 收藏0
  • 介绍RxJS在Angular中应用

    摘要:是一种针对异步数据流编程工具,或者叫响应式扩展编程可不管如何解释其目标就是异步编程,引入为了就是让异步可控更简单。最合理的方式在调用它。当组件需要向组件传递数据时,我们可以在组件中使用。的作用是使指令或组件能自定义事件。 RxJS是一种针对异步数据流编程工具,或者叫响应式扩展编程;可不管如何解释RxJS其目标就是异步编程,Angular引入RxJS为了就是让异步可控、更简单。 而今就是...

    joyqi 评论0 收藏0
  • 从命令式到响应式(十)

    摘要:加上以后的操作符大都是直接将输入流映射到一个输出流,并且它们都不关心输入流上的值。如果输入流没发出任何值,只发出完成通知,那么发出一个默认值。与错误相关的一些操作符,如已经提到的当输入流上有错误时,可以发出重试,传入的参数就是重试的次数。 这个系列不知不觉已经写到10了,单纯从使用上来说的话,大部分的知识点也都讲过了,本来不打算写了,刚好今天有同学在群里说希望能总结一下常用的操作符,那...

    kycool 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<