一.函數(shù)式編程
函數(shù)式編程要求:
- 聲明式
- 純函數(shù)
- 數(shù)據(jù)不可變
js 不算純粹意義上的函數(shù)式編程語言吐根,但是,在js中函數(shù)被稱為一等公民专执,函數(shù)本身是一個(gè)對(duì)象飞几,所以可以作為一個(gè)變量,可以作為參數(shù)傳遞缩膝。
純函數(shù)滿足的條件: - 函數(shù)的執(zhí)行過程完全由輸入?yún)?shù)決定混狠,不會(huì)受參數(shù)之外的任何數(shù)據(jù)影響
- 函數(shù)不會(huì)修改任何外部狀態(tài),比如修改全局變量疾层,傳入的參數(shù)将饺。
面向?qū)ο笏枷耄喊褦?shù)據(jù)封裝到類的實(shí)例對(duì)象,把數(shù)據(jù)藏起來痛黎,讓外部不能直接操作這些對(duì)象予弧,只能通過類提供的實(shí)例方法來讀取和修改這些操作,這樣就限制了對(duì)象的訪問方式
FRP(Functional Reactive Programming)包含兩個(gè)重要元素:指令性和臨時(shí)的連續(xù)性
函數(shù)響應(yīng)式編程的優(yōu)勢(shì)
- 數(shù)據(jù)流抽象了很多現(xiàn)實(shí)問題
- 擅長(zhǎng)處理異步操作
- 把復(fù)雜問題分解成簡(jiǎn)單問題的組合
Rxjs擅長(zhǎng)處理異步操作湖饱,因?yàn)樗鼘?duì)數(shù)據(jù)采用推的處理方式掖蛤,當(dāng)一個(gè)數(shù)據(jù)產(chǎn)生的時(shí)候,就推送給對(duì)應(yīng)的處理函數(shù)井厌,這個(gè)處理函數(shù)不用關(guān)心數(shù)據(jù)是同步產(chǎn)生的還是異步產(chǎn)生的蚓庭,解決了處理異步的枷鎖。
二.RxJs入門
在webpack中有一個(gè)打包工具仅仆,tree-shaking,這個(gè)工具包的用處是在打包過程中發(fā)現(xiàn)根本沒有用上的函數(shù)器赞,最終在打包的文件中就不會(huì)包含進(jìn)去.
Tree-Shaking只會(huì)對(duì)import語句產(chǎn)生作用,對(duì)require語句不起效果墓拜,由于import只能在代碼頂層出現(xiàn)港柜,不可以使用if,而且被導(dǎo)入等等模塊一字符串常理出現(xiàn)咳榜,所以import完全滿足靜態(tài)分析的需求潘懊,但是require可以出現(xiàn)在if中參數(shù)也可以是動(dòng)態(tài)產(chǎn)生的字符串,只有在執(zhí)行時(shí)才會(huì)知道require如何執(zhí)行贿衍,所以tree-shaking對(duì)require不起效果
1. Observable和Observer
Observable: 被觀察者
Observer:觀察者
鏈接兩者的橋梁是Observable對(duì)象的函數(shù)subscrible
Observable實(shí)現(xiàn)了兩種設(shè)計(jì)模式:
觀察者模式 (Observer Pattern)/ 迭代器模式(Iteraor Pattern)
觀察者模式
觀察者模式要解決的問題,就是在一個(gè)持續(xù)產(chǎn)生事件的系統(tǒng)中如何分割功能救恨,讓不同模塊只需要處理一部分邏輯贸辈。
Observable對(duì)象就是一個(gè)發(fā)布者,通過Observable對(duì)象的subscribe函數(shù),可以把這個(gè)發(fā)布者和某個(gè)觀察者(observer)連接起來
迭代器模式
迭代者(Iterator)指的是能夠遍歷一個(gè)數(shù)據(jù)集合的對(duì)象擎淤,其作用就是提供一個(gè)通用的接口奢啥,讓使用者完全不關(guān)心這個(gè)數(shù)據(jù)集合的具體實(shí)現(xiàn)方式。
迭代器(又叫:游標(biāo) cursor)就像一個(gè)移動(dòng)的指針嘴拢,從集合中的一個(gè)元素移動(dòng)到另一個(gè)元素桩盲,完成對(duì)整個(gè)集合的遍歷
通常包含幾個(gè)函數(shù):
- getCurrent:獲取當(dāng)前被游標(biāo)所指向的元素
- moveToNext:將游標(biāo)移動(dòng)到下一個(gè)元素,調(diào)用這個(gè)函數(shù)之后席吴,getCurrent獲得的元素就會(huì)不同
- isDone: 判斷是否已經(jīng)遍歷完所有的元素
在rxjs中將觀察者模式和迭代器兩種模式結(jié)合起來的優(yōu)勢(shì):
不需要主動(dòng)從observable中pull數(shù)據(jù)赌结,而是只要subscribe上observable對(duì)象之后,自然就能夠收到消息的推送
Observable是永無止境的
Observable對(duì)象每次只吐出一個(gè)數(shù)據(jù)孝冒,然后這個(gè)數(shù)據(jù)就被Observable消化處理了柬姚,不會(huì)存在數(shù)據(jù)的堆積
和數(shù)組不同之處是,內(nèi)存的消耗會(huì)隨著數(shù)組的大小而改變庄涡。
數(shù)據(jù)流是永無止境的量承。
Observable在subscribe之后有四個(gè)狀態(tài):next / error / complete(完成) / dispose(退訂) - complete:調(diào)用complete之后不會(huì)再調(diào)用next,Observable告訴observer程序已經(jīng)完結(jié)
- error :一旦調(diào)用error 之后表示Observable對(duì)象已經(jīng)完結(jié)穴店,不會(huì)再調(diào)用complete方法
- dispose:有subscribe訂閱也就會(huì)有取消訂閱的操作(dispose),在dispose之后就不會(huì)再收到Observable產(chǎn)生的事件了
Hot Observable和Cold Observable
- Hot Observable:概念上是有一個(gè)獨(dú)立于Observable對(duì)象的生產(chǎn)者撕捍,這個(gè)生產(chǎn)者的創(chuàng)建和subscribe調(diào)用沒有關(guān)系,subscribe調(diào)用只是讓Observer連接上生產(chǎn)者泣洞。
- Cold Observable: 對(duì)每一次的subscribe都產(chǎn)生一個(gè)producer,然后這個(gè)producer產(chǎn)生的數(shù)據(jù)通過next函數(shù)傳遞給Observer
Cold Observable
const cold$ = new Observable(observer => {
const producer = new producer()
})
Hot Observable
const producer = new producer()
const cold$ = new Observable(observer => {
})
小結(jié):
- Observable和Observer是rxjs兩大主角忧风,這兩者的關(guān)系是觀察者和迭代器模式的結(jié)合,通過Observable對(duì)象的subscribe函數(shù)斜棚,可以讓一個(gè)Observer對(duì)象訂閱某個(gè)Observable對(duì)象的推送內(nèi)容阀蒂,也可以通過unsubscribe函數(shù)退訂內(nèi)容
- 在 Observable和Observer兩者的關(guān)系里,Observer處于被動(dòng)地位弟蚀,在代碼中看不到Observer對(duì)象蚤霞,只可以看到next,error,complete的函數(shù)
- Observable對(duì)象可以看作一個(gè)數(shù)據(jù)集合,但是這個(gè)數(shù)據(jù)集合可以不是一次產(chǎn)生的义钉,而是在一個(gè)時(shí)間段內(nèi)逐個(gè)產(chǎn)生數(shù)據(jù)昧绣,所以這就是一個(gè)Observable對(duì)象即使產(chǎn)生龐大的數(shù)據(jù),但是并不會(huì)消耗很多內(nèi)存的原因捶闸,因?yàn)槊看沃划a(chǎn)生一個(gè)吐出來之后在產(chǎn)生另一個(gè)夜畴,不會(huì)積壓