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]数组。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/536103.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于Loss的简单总结

Dice Loss 参考:https://blog.csdn.net/l7H9JA4/article/details/108162188 Dice系数: 是一种集合相似度度量函数,通常用于计算两个样本的相似度,取值范围为[0,1]。 s2∣X∩Y∣∣X∣∣Y∣s \frac{2|X ∩ Y|}{|X||Y|} s∣X∣∣Y…

Angular_PWA使用+Demo

Angular_PWA使用+Demo 什么是PWA PWA(Progressive Web App)利用TLS,webapp manifests和service workers使应用程序能够安装并离线使用。 换句话说,PWA就像手机上的原生应用程序,但它是使用诸如HTML5,JavaScript和CSS3之类的网络技术构建的。 如果构建正确,PWA与原生应…

SOLOv2论文简读

论文:SOLOv2: Dynamic, Faster and Stronger 代码:https://github.com/WXinlong/SOLO 摘要 主要提出了作者在SOLOv2中实现的优秀的实例分割方法,旨在创建一个简单、直接、快速的实例分割框架: 通过提出动态学习对象分割器的mas…

Angular6_PWA

Angular6_PWA Angular正式发布了V6.0,我们已经可以利用对应的@angular/cli V6.0来直接开发PWA应用了。 第一步:安装@angular/cli V6.0 如果你机器上有老版本,请先卸载。 打开你的终端,执行: npm install -g @angular/cli 或 cnpm install -g @angular/cli 安装成功…

Ubuntu18.04 关于使用vnc的踩坑

由于种种原因,手上多了一台可使用的桌面版Ubuntu,正好用来测试代码,方便调试。因为只能远程,所以需要配置远程连接。因此就打算使用vnc进行远程连接,谁料一路坎坷,特此记录。 安装 设置桌面共享 需要注意…

App_Shell模型

App_Shell模型 App Shell 架构是构建 Progressive Web App 的一种方式,这种应用能可靠且即时地加载到您的用户屏幕上,与本机应用相似。 App shell是支持用户界面所需的最小的 HTML、CSS 和 JavaScript,如果离线缓存,可确保在用户重复访问时提供即时、可靠的良好性能。这意…

Angular6_服务端渲染SSR

Angular6_服务端渲染 在使用服务端渲染之前,需要安装最新版本的Angular。 npm install -g @angular/cli 或 cnpm install -g @angular/cli github项目 创建项目 ng new PWCat --routing 为项目添加universalng g universal --client-project=PWCat 或

Jenkins自定义主题教程

Jenkins自定义主题 由于Jenkins自带的样式比较丑陋,所以有很多第三方的样式库,这里针对jenkins-material-theme样式库做一个安装教程。 下载样式库 下载连接 Select your color 选择一个你喜欢的主题颜色。Choose your company logo 上传你自定义的…

IndexedDB_Web 离线数据库

IndexedDB_Web 离线数据库 本文会从头剖析一下 IndexedDB 在前端里面的应用的发展。 indexedDB 目前在前端慢慢得到普及和应用。它正朝着前端离线数据库技术的步伐前进。以前一开始是 manifest、localStorage、cookie 再到 webSQL,现在 indexedDB 逐渐被各大浏览器认…

Angular 单元测试讲解

Angular_单元测试 测试分类 按开发阶段划分按是否运行划分按是否查看源代码划分其他ATDD,TDD,BDD,DDD ATDDTDDBDDDDDAngular单元测试 Karma的介绍jasmine介绍单元测试的好处使用jasmine和karma创建一个Angular项目Karma配置Test.ts文件测试体验测试Form测试服务service常用断言…

基于 Docker 的微服务架构

基于 Docker 的微服务架构-分布式企业级实践前言Microservice 和 Docker服务发现模式客户端发现模式Netflix-Eureka 服务端发现模式ConsulEtcdZookeeper 服务注册自注册模式 Self-registration pattern第三方注册模式 Third party registration pattern小结一 服务间的 IPC 机制…

funcode游戏实训,java及C/C++,网上整理

软件,常见错误都有。 所有资源可到公众号获取(源码也是),不再直接分享

Docker 容器部署 Consul 集群

Docker 容器部署 Consul 集群 Consul 介绍 Consul 提供了分布式系统的服务发现和配置的解决方案。基于go语言实现。并且在git上开放了源码consul-git。consul还包括了分布式一致协议的实现,健康检查和管理UI。Consul和zk相比较起来,更加轻量级&#xf…

swing皮肤包 substance

分享一下swing皮肤包substance 资源可到公众号获取

基于Android的聊天软件,Socket即时通信,实现用户在线聊天

基于Android的聊天软件,Socket即时通信,单聊,聊天室,可自行扩展功能,完善细节。 【实例功能】 1.运行程序,登录界面, 注册账号功能 2.进入主界面,有通讯录, 个人信息。 3.点击好友会话框&#…

用Docker搭建Elasticsearch集群

用Docker搭建Elasticsearch集群 对于用Docker搭建分布式Elasticsearhc集群的一个介绍,以及一些实施中遇到问题的总结 搜索服务简述 结合业务的场景,在目前的商品体系需要构建搜索服务,主要是为了提供用户更丰富的检索场景以及高速&#xf…

Go实现简单的RESTful_API

Go实现简单的RESTful_API 何为RESTful API A RESTful API is an application program interface (API) that uses HTTP requests to GET, PUT, POST and DELETE data. A RESTful API – also referred to as a RESTful web service – is based on representational state t…

Docker使用Dockerfile构建简单镜像

Docker使用Dockerfile构建简单镜像 首先确保系统已经安装docker 构建镜像 安装基础镜像 sudo docker pull ubuntu 查看镜像是否已经拉取成功 REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu …

Weave Scope安装

Weave Scope安装 首先确保已经安装docker 实时了解Docker容器状态 查看容器基础设施的概况,或者专注于一个特殊的微服务。从而轻松发现并纠正问题,确保你的容器化应用的稳定与性能。 内部细节与深度链接 查看容器的指标、标签和元数据。 在一个可扩展…

MYSQL导入数据出现ERROR 1049 (42000): Unknown database 'n??;'

MYSQL导入数据出现ERROR 1049 (42000): Unknown database ‘n??;’ 背景 我需要将一个csv表中的数据导入数据库创建好的表中,产生的问题如下: 原因寻找 因为我并没有使用’n??;的数据库,所以很好奇这个错怎么来的,尝试如下…