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.pswp.cn/news/536103.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/536103.shtml
英文地址,請注明出處:http://en.pswp.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??;的數據庫,所以很好奇這個錯怎么來的,嘗試如下…