欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Rxjs的flatMap使用

发布时间:2025/3/8 49 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Rxjs的flatMap使用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

Rxjs的flatMap使用

flatMap是Rxjs比较绕的一个概念,这里我们只是讲解如何使用。在Rxjs 4.0版本时叫flatMap,在Rxjs 5.0时被更名为margeMap,现在flatMap作为margeMap的别名使用,这是考虑向下兼容。

官方flatMap的定义:
Projects each source value to an Observable which is merged in the output Observable.

mergeMap(project: function(value: T, ?index: number): ObservableInput, resultSelector: function(outerValue: T, innerValue: I, outerIndex: number, innerIndex: number): any, concurrent: number): Observable 名称类型属性描述
projectfunction(value: T, ?index: number): ObservableInput函数,当应用于源 Observable 发出的项时,返回一个 Observable 。
resultSelectorfunction(outerValue: T, innerValue: I, outerIndex: number, innerIndex: number): any可选的函数,它用于产生基于值的输出 Observable 和源(外部)发送和内部 Observable 发送的索引。传递给这个函数参数有:
outerValue: 来自源的值
innerValue:来自投射的Observable 的值
outerIndex: 来自源的值的 “index”
innerIndex: 来自投射的 Observable 的值的 “index”
concurrentnumber可选的,默认值: Number.POSITIVE_INFINITY可以同时订阅的输入 Observables 的最大数量。

返回:
Observable
该 Observable 发出由源 Observable 发出的每项应用投射函数 (和可选的 resultSelector)后的结果,并合并从该转化获得的 Observables 的结果。

Demo

var source = Rx.Observable.of(1,2,3).flatMap(function (x, i) {console.log(`x:${x},i:${i}`);return [x, i];},function (x, y, ix, iy) { console.log(`x:${x},y:${y},ix:${ix},iy:${iy}`);return x + y + ix + iy;}); var subscription = source.subscribe(function (x) { console.log(x);});

JSBin运行:

"x:1,i:0" "x:1,y:1,ix:0,iy:0" 2 "x:1,y:0,ix:0,iy:1" 2 "x:2,i:1" "x:2,y:2,ix:1,iy:0" 5 "x:2,y:1,ix:1,iy:1" 5 "x:3,i:2" "x:3,y:3,ix:2,iy:0" 8 "x:3,y:2,ix:2,iy:1" 8

分享一下流程:
- flatMap将1,2,3数据流一次传入flatMap的第一个回调函数,然后输出”x:1,i:0”
- 然后返回[1,0]数组给第二个回调函数,这里的1是value,0是index,是数据的索引号
- 输出”x:1,y:1,ix:0,iy:0”,然后返回2,这里的x参数是outerValue,y是innerValue,ix,是outerIndex,iy是innerIndex
- 在订阅的回调函数中输出2
- 其中的innerValue回退到上一次的值,对应的索引增加,此时值为”x:1,y:0,ix:0,iy:1”,然后返回2
- 在订阅的回调函数中输出2
- 接下来flatMap接受值2,然后传入第一个回调函数project,”x:2,i:1”,返回[2,1]
- 将[2,1]传入第二个回调函数resultSelector,输出”x:2,y:2,ix:1,iy:0”,返回5
- 在订阅的回调函数中输出5
- 然后resultSelector回调函数又一次被调用,传入的参数(2,1,1,1),输出”x:2,y:1,ix:1,iy:1”,并返回5
- 在订阅的回调函数中输出5

下面依次类推,注意的一点是,resultSelector函数会被调用两次,第一次innerValue为当前投射的值,第二次innerValue为上一次的值。

为了验证我们的想法将flatMap的project函数返回值为[x]

var source = Rx.Observable.of(1,2,3).flatMap(function (x, i) {console.log(`x:${x},i:${i}`);return [x];},function (x, y, ix, iy) { console.log(`x:${x},y:${y},ix:${ix},iy:${iy}`);return x + y + ix + iy;}); var subscription = source.subscribe(function (x) { console.log(x);});

输出结果:

"x:1,i:0" "x:1,y:1,ix:0,iy:0" 2 "x:2,i:1" "x:2,y:2,ix:1,iy:0" 5 "x:3,i:2" "x:3,y:3,ix:2,iy:0" 8

根据结果我们能够发现resultSelector函数的执行次数取决于project的返回值。那么我们继续修改返回值为[x,1]

var source = Rx.Observable.of(1,2,3).flatMap(function (x, i) {console.log(`x:${x},i:${i}`);return [x,1];},function (x, y, ix, iy) { console.log(`x:${x},y:${y},ix:${ix},iy:${iy}`);return x + y + ix + iy;}); var subscription = source.subscribe(function (x) { console.log(x);});

输出结果:

"x:1,i:0" "x:1,y:1,ix:0,iy:0" 2 "x:1,y:1,ix:0,iy:1" 3 "x:2,i:1" "x:2,y:2,ix:1,iy:0" 5 "x:2,y:1,ix:1,iy:1" 5 "x:3,i:2" "x:3,y:3,ix:2,iy:0" 8 "x:3,y:1,ix:2,iy:1" 7

结论:

根据这个结果我们能够总结resultSelector函数的y值取决于[x,i]中的i,如果i为0,那么y的值第一次等于x,然后不发生变化。如果i为1那么y第一次等于x,然后需要回退到当前i的值。如果i为2,那么y会从当前的x变化到i,这期间iy的值会从0变化为1。


千万不要高兴的太早,刚刚的结论我们只是尝试着去总结,但是不幸的是错的,没错,比如我们做如下修改

var source = Rx.Observable.of(1,2,3).flatMap(function (x, i) {console.log(`x:${x},i:${i}`);return [2, i];}, // 修改这里function (x, y, ix, iy) { console.log(`x:${x},y:${y},ix:${ix},iy:${iy}`);return x + y + ix + iy;}); var subscription = source.subscribe(function (x) { console.log(x);});

返回结果

"x:1,i:0" "x:1,y:2,ix:0,iy:0" 3 "x:1,y:0,ix:0,iy:1" 2 "x:2,i:1" "x:2,y:2,ix:1,iy:0" 5 "x:2,y:1,ix:1,iy:1" 5 "x:3,i:2" "x:3,y:2,ix:2,iy:0" 7 "x:3,y:2,ix:2,iy:1" 8

这个结果说明什么呢,project返回的数组决定resultSelector回调函数中的y,而resultSelector回调函数中的x是不受影响的,取决于外界传入的值。当project返回的数组中[2,i],决定y的触发次数,如果有两个数组元素就被触发2次,有5个数组元素那么就被触发5次。

最终结论:
resultSelector
project回调函数的返回值决定resultSelector回调函数的参数y即innerValue,同时也决定resultSelector回调函数被触发几次。

如果将flatMap的第二个回调函数去除

var source = Rx.Observable.of(1,2,3).flatMap(function (x, i) {console.log(`x:${x},i:${i}`);return [x, i];}); var subscription = source.subscribe(function (x) { console.log(x);});

JSBin结果

"x:1,i:0" 1 0 "x:2,i:1" 2 1 "x:3,i:2" 3 2

我们可以看到这是正常的结果,flatMap返回Observable的[x,i]数组。

总结

以上是生活随笔为你收集整理的Rxjs的flatMap使用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。