Rxjs操作符之forkJoin, zip, combineLatest间的区别

1,968 阅读3分钟

前言

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

区别在什么时间呈现了? 只有当其操作的流会多次发射数据时才会体现出它们之间的区别 为了方便理解,说明下 一个流的生命周期,next、complte、error;发射数据时走next,结束发射时走complete,发射出错时走error,事件complete和error都表示了生命周期结束, 后面说到index表示一个流发的数据是第几个next

事例

import { interval, combineLatest, forkJoin, zip } from 'rxjs'; 
import { delay, take } from 'rxjs/operators';


const a = interval(1000).pipe(
  take(2)
);
const b = interval(1000).pipe(
  delay(1000),take(2)
);
const c = interval(1000).pipe(
  delay(3000), take(5)
);
combineLatest(a, b, c).subscribe(res => console.log(res)) 
// [1, 1, 0]
// [1, 1, 1]
// [1, 1, 2]
// [1, 1, 3]
// [1, 1, 4]
zip(a, b, c).subscribe(res => console.log(res)) 
// [0, 0, 0]
// [1, 1, 1]
forkJoin(a, b, c).subscribe(res => console.log(res))
// [1, 1, 4]

forkJoin

会在每个被合并的流都发出结束信号时发射一次数据也是唯一一次数据,如下上面代码 a在2秒时到得1数据,b在3秒时得到1,c在8秒后得到4数据,forkJoin在8秒后返回[1, 1, 4]

zip

会在每个合并流中每个都发出了第一次时返回第一次数据,有多少次index相同就会发多少次数据,a和b的index有 0,1;c的index有 0,1,2,3,4,所以相同点只有 0和1所以只会有两次数据返回,第一次是4秒时返回[0, 0, 0] 第二次是5秒时返回[1,1,1],后面a和b都结束了流所以没有数据了

combineLatest

会等待每个子流都发射完一次数据,返回第一次数据,合并数据时是取其最新发射的数据合并,之后任一字流发射新数据,不再等待其他子流同步发射数据,而是使用其他流之前的最新一次数据进行合并,如上代码,当c拿到第一次数据时,a、b都发射了2次数据并结束了流,全并取最新后以第一次数据为[1, 1, 0],后面c发身第二条数据时(a、b没有发射数据),返回[1, 1, 1],以此类推直到c发完最后一条数据返回[1. 1. 4]

区别

只拿最后一次数据用forkJoin
依序拿数据用zip
等待拿第一次数据,后子流只要发射数据就拿一次数据用combineLatest

在线代码示例

文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注

本文使用 mdnice 排版