前置:我目前的學(xué)習(xí)資料是30天精通RxJS,那個(gè)時(shí)候的RxJS是5.x版本,而目前最新版本是RxJS 6,所以資料會放一部分5.x的代碼,我也會自己將他轉(zhuǎn)錄成RxJS6的版本贷祈,可以做一個(gè)對比。
學(xué)習(xí)前置:需要JavaScript的相關(guān)知識喝峦,了解Ajax势誊,會用控制臺,最好有ES6和node.js的基礎(chǔ)谣蠢。
在線代碼平臺:JS Bin
為什么學(xué)習(xí)RxJS
目前剛進(jìn)公司粟耻,權(quán)限很多都沒批下來,因?yàn)楣镜那岸丝蚣苡玫氖茿ngular眉踱,而Angular的腳手架工具自帶RxJS的包挤忙,所以準(zhǔn)備自學(xué)一下。
一接觸感覺這個(gè)庫真的很不錯(cuò)谈喳,首先他并不是依賴于Angular的一個(gè)庫册烈,無論你使用React,Angular甚至是原生JavaScript婿禽,都可以使用這個(gè)庫赏僧,據(jù)說在新的ES版本中正打算將其直接引入原生的JavaScript中。這也就意味著學(xué)習(xí)RxJS不需要有Angular的前置技能需求谈宛,不需要你了解前端的MVVM框架次哈,也不需要了解TypeScript,只需要有原生JavaScript的基礎(chǔ)以及對異步有初步的了解吆录,懂得JavaScript中部分異步(setInterval窑滞,setTimeout以及ajax等等)的內(nèi)容便可以學(xué)習(xí)了。
其次使用RxJS能簡化很多涉及到異步執(zhí)行的操作恢筝,在處理異步方面有點(diǎn)類似Promise哀卫,可以很好的處理異步信息,不會陷入無限多的回調(diào)函數(shù)撬槽,使得異步調(diào)用的過程清晰而有條理此改;同時(shí)也支持同步信息的處理,也可以將同步數(shù)據(jù)轉(zhuǎn)化成異步輸出的信息侄柔。
同時(shí)RxJS提供了豐富的operator可以對Observable進(jìn)行處理共啃,這一部分很像LinQ,數(shù)據(jù)的處理也同LinQ一樣非常直觀暂题,這是promise所不具備的功能移剪。
而與async/await相比,無論對于學(xué)習(xí)來說還是對開發(fā)來說都相當(dāng)利于理解薪者,學(xué)習(xí)成本更低纵苛。
RxJS基礎(chǔ)部分:安裝與引用
學(xué)習(xí)5.x的可以不需要安裝node.js
頁面中引入RxJS<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.1/Rx.js"></script>
如果希望學(xué)習(xí)6.x的需要一些es6以及nodejs的基礎(chǔ)
1.在官網(wǎng)下載并安裝node.js
2.1.通過cmd輸入如下命令安裝angular腳手架npm install -g @angular/cli
2.2.不希望學(xué)習(xí)Angular的可以直接安裝RxJSnpm install -g rxjs
3.在代碼中import { 你需要使用的模塊名 } from 'rxjs'
需要引用哪些模塊我將會在代碼中給出。
5.x版本以及6.x版本理念是相同的,只不過代碼版式略有不同攻人。
RxJS基礎(chǔ)部分:Observable
observable是RxJS的核心之一取试,直譯是可觀測的物體,在實(shí)例中一般是我們的所需要獲取的數(shù)據(jù)源怀吻,以下是一段簡單的創(chuàng)建observable對象的代碼瞬浓。
//5.x版本
var observable = Rx.Observable // 創(chuàng)建一個(gè)observable對象.create(function(observer) {
observer.next('Jerry'); // 同步部分
observer.next('Anna');
setTimeout(() => { // 異步部分
observer.next('RxJS!');
observer.complete(); //停止observable,此后部分不會被顯示烙博。
observer.next("not work");
}, 300)
})
//6.x版本瑟蜈,可以發(fā)現(xiàn)這里沒有Rx.
//你需要在這之前import {Observable} from 'rxjs'
var observable = Observable.create(observer => {
observer.next("Jerry");
observer.next("Anna");
setTimeout(() => {
observer.next('RxJS!');
observer.complete();
observer.next("not work");
}, 300)
});
create()方法是直接創(chuàng)建一個(gè)observable對象的方法,該方法的參數(shù)是一個(gè)函數(shù)渣窜,其中規(guī)劃了observable將來的走向铺根。
我們一般不會再實(shí)例中直接這樣定義一個(gè)人為的observable,不過這有助于我們理解observable內(nèi)的三個(gè)命令(上面有兩個(gè))乔宿。
一個(gè)是next()位迂,next顧名思義下一個(gè)數(shù)據(jù),指的是observable中將會被觀測到的下一個(gè)數(shù)據(jù)详瑞,這里的observer.next()中的參數(shù)則會作為observable的輸出掂林。
第二個(gè)是complete(),observable在沒有complete前將會一直打開坝橡,complete則會關(guān)閉這個(gè)observable泻帮,之后再輸出的next將不會有反應(yīng),就如同上述代碼的not work计寇,將是不會被輸出的锣杂。
看到這里,有自己試著寫代碼的人肯定會問我番宁,不止not work元莫,我在瀏覽器里什么都沒有看見,這個(gè)代碼是不是寫錯(cuò)了蝶押?
代碼并沒有錯(cuò)踱蠢,但observable只是一個(gè)可以被觀察的對象,世間有千千萬萬可以被觀測的東西棋电,只有你去注意茎截,才能注意到事物發(fā)出的信息,這個(gè)注意的動作赶盔,叫做subscribe稼虎。
RxJS基礎(chǔ)部分:Subscribe
試著在上述代碼下加上如下代碼(這里5.x和6.x的寫法是一樣的,以后沒有特別提示RxJs的版本的代碼將會是兩者通用的)招刨,摁下F12,進(jìn)入console,觀察一下控制臺的輸出是否和注釋相同沉眶。
console.log('start');
observable.subscribe(function(value) {
// 訂閱這個(gè)observable對象打却,并為其設(shè)置觀察者方法。
console.log(value);
});
console.log('end');
//start
//Jerry
//Anna
//end
//RxJS!
正如上一小節(jié)所說谎倔,RxJS具有同時(shí)處理同步和異步的能力柳击,我們可以發(fā)現(xiàn)同步輸出的Jerry與Anna插在了start與end之間,而異步輸出的RxJS!則在end之后輸出片习,complete之后的not work則沒有出現(xiàn)捌肴。
大家可以試試把comlete放到setTimeout的外面一試,這樣更能證明observable同時(shí)處理同步以及異步的能力藕咏。
subscribe不僅只有處理next的能力状知,和promise類似,subscribe有自己的對于不同狀態(tài)的處理孽查,請看如下代碼:
observable.subscribe( {
next: function(value) { //next()走這里
console.log(value);
},
error: function(error) { // 出現(xiàn)異常走這里
console.log('Error: ', error)
},
complete: function() { //complete()走這里
console.log('complete')
}
})
//lambda表達(dá)式寫法
observable.subscribe(
v => { console.log(v); },
e => { console.log('Error: ', e); },
() => { console.log('complete') }
)
subscribe可以傳入三個(gè)函數(shù)以來應(yīng)對三個(gè)不同的情況
第一個(gè)函數(shù)參數(shù)用于處理next()
第二個(gè)函數(shù)參數(shù)用于處理內(nèi)部處理過程中拋出的異常
第三個(gè)函數(shù)則用于處理complete信號饥悴,可以用上述代碼替換最早的subscribe代碼,看看情況有什么變化盲再。
subscribe也有一個(gè)自己的返回值西设,是一個(gè)subscription對象,我們可以利用這個(gè)對象的unsubscribe方法去結(jié)束某些無法complete的observable(未來我們會見到不少)答朋。
var _subscription = observable.subscribe(function({
......
}))
_subscription.unsubscribe();
本章小結(jié)
這一小節(jié)的內(nèi)容相對簡單贷揽,主要介紹了如何引用RxJS以及RxJS最基礎(chǔ)也是最核心的兩個(gè)部分。
下一章我們將會接觸到另一個(gè)核心部分梦碗,operator禽绪,操作符。
附錄
30天精通RxJS叉弦,我是在readilen的簡書上閱讀的轉(zhuǎn)載丐一,原作者應(yīng)該是臺灣的一位前端工程師Jerry Hong,有興趣的可以去拜讀一下原文淹冰,有很多概念性的東西我沒有提到库车,我這篇主要工作是自己總結(jié)并分享我的學(xué)習(xí)記錄,并將老版本更新為新版本代碼樱拴。
其中大部分思考與看法源于個(gè)人柠衍,如果有錯(cuò)誤的話希望各位不吝賜教,這兩天我大概學(xué)習(xí)了十多章晶乔,這個(gè)周末我會盡快把這些整理出來珍坊。