我們知道Observable是個(gè)容器,里面包含著數(shù)據(jù),數(shù)據(jù)從何而來(lái)肛跌?
靜態(tài)數(shù)據(jù)
我們?nèi)粘V囟仁褂玫?code>string和array
都屬于此范疇。
動(dòng)態(tài)數(shù)據(jù)
比如我們用ES6中的generator
生成斐波那契數(shù)列,比如通過RESTful api調(diào)用返回的數(shù)據(jù)衍慎。
Observables發(fā)送事件转唉,Observer異步地接收事件,這可以讓我們的應(yīng)用在有大量事件產(chǎn)生的時(shí)候保持響應(yīng)能力稳捆。強(qiáng)調(diào)一下赠法,RxJS不是僅面向客戶端js的,在服務(wù)端同樣可以使用乔夯∽┲看下代碼:
Rx.Observable.from(<數(shù)據(jù)源>)
.operator1(...)
.operator2(...)
.operator3(...)
.subscribe(<處理最終結(jié)果數(shù)據(jù)>)
再?gòu)?qiáng)調(diào)兩個(gè)事情,第一驯嘱,observables是個(gè)不可變數(shù)據(jù)類型镶苞,像string一樣;第二鞠评,observables不僅僅代表了當(dāng)前時(shí)刻的數(shù)據(jù)茂蚓,也代表了未來(lái)某時(shí)刻的數(shù)據(jù)。
何時(shí)何地用RxJS
世間沒有萬(wàn)能藥剃幌,RxJS也一樣聋涨,只在適合它的地方使用它。我們把程序按照兩個(gè)維度劃分成一個(gè)田字表格负乡,橫向是單值牍白,多值,縱向是同步抖棘,異步茂腥。
單值,同步
用Rx.Observable.of來(lái)包裝單值同步數(shù)據(jù):
Rx.Observable.of(2017)
一旦有消費(fèi)者消費(fèi)切省,此值馬上被發(fā)送出去最岗。這種情況下使用RxJS顯得有點(diǎn)重了,除非我們想進(jìn)行合并流的操作朝捆。
多值般渡,同步
用Rx.Observable.from來(lái)包裝多值同步數(shù)據(jù):
Rx.Observable.from([1, 2, 3])
from()函數(shù)可能是RxJS中最常用的之一了。同步在這里是啥意思呢芙盘?就是說1處理完了才能處理2驯用,2處理完了才能處理3。如果1處理得慢儒老,2必須等著蝴乔,以此類推。
單值贷盲,異步
這個(gè)情況其實(shí)就是Promise淘这。RxJS提供了函數(shù)可以無(wú)縫地和Promise整合到一起剥扣。
const one = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1);
}, 3000);//模擬3秒延遲
});
//這個(gè)時(shí)候Promise中的代碼已經(jīng)在運(yùn)行了
Rx.Observable.fromPromise(one)
.map(value => value = value + 1);
.subscribe(result => {
console.log(result);
});
console.log("程序結(jié)束");
由于是異步程序巩剖,一運(yùn)行就會(huì)打印“程序結(jié)束”铝穷,3秒后將打印2。然而用Observable包裝一層有啥意義佳魔?意義在于Promise是無(wú)法重新運(yùn)行的曙聂,而Observable可以,并且還可以讓它運(yùn)行很多次鞠鲜,這是通過內(nèi)嵌Observable來(lái)實(shí)現(xiàn)的宁脊,我們后面會(huì)講到。
多值贤姆,異步
這個(gè)場(chǎng)景就是我們常說的事件驅(qū)動(dòng)的異步編程玖院。比如DOM事件以及NodeJS中的EventEmitter琐鲁。如何使用RxJS包裝DOM事件,如下圖:
這里我用的是https://jsfiddle.net/。點(diǎn)擊span標(biāo)簽摹闽,在控制臺(tái)打印出span標(biāo)簽中的href屬性值。
EventEmitter的包裝在這里我們就暫時(shí)不講了垫挨,以后碰上再說跛溉。感興趣的可以看下RxJS的文檔。
拉模型與推模型
迭代器就是基于拉的獲取數(shù)據(jù)的代表砰碴。最有代表性的示例就是利用ES6中的Generator來(lái)生成斐波那契數(shù)列躏筏。Generator的教程請(qǐng)參見http://es6.ruanyifeng.com/#docs/generator〕释鳎基于拉的獲取數(shù)據(jù)的方式就是我想要數(shù)據(jù)的時(shí)候才去獲取數(shù)據(jù)趁尼,是主動(dòng)的去獲取數(shù)據(jù)。
而Observable是基于推的獲取數(shù)據(jù)方式的猖辫。數(shù)據(jù)會(huì)主動(dòng)推送給我酥泞,我被動(dòng)地接收數(shù)據(jù)做出響應(yīng)。
以上說了那么多住册,想表明一件事就是婶博,RxJS可以用同樣的方式來(lái)處理同步和異步編程,并且把如何產(chǎn)生數(shù)據(jù)和如何消費(fèi)數(shù)據(jù)各自獨(dú)立出來(lái)荧飞。
我們可以把一切東西都轉(zhuǎn)換成Observable凡人,但是應(yīng)該不應(yīng)該就要視情況而定了。比如轉(zhuǎn)換字符串大小寫叹阔,直接用string的方法就可以了挠轴。RxJS中的任何操作都會(huì)有性能損失。