原做者:一名來自臺灣的小夥子,熱愛學習新技術,喜歡 JS 與 Functional Programming,熱衷於把困難的技術用簡單的語言闡述,歡迎來到個人文章。html
原文vue
在網頁中存取數據都是異步(Async)的,好比說咱們想從後端拿到一組數據,要先發送一個請求,而後必須等到數據回來,再執行對這個數據的操做。這就是一個異步的行爲,而隨着網頁需求的複雜化,咱們所寫的 JavaScript 就有各鍾針對異步行爲的寫法,例如使用 callback 或是 Promise 對象甚至是新的語法糖 async/await —— 但隨着應用需求愈來愈複雜,撰寫非同步的代碼仍然很是困難。react
當咱們對同一個資源同時作屢次的異步存取時,就可能發生 Race Condition 的問題。好比說咱們發了一個 Request 更新使用者資料,而後咱們又當即發送另外一個 Request 取得使用者資料,這時第一個 Request 和第二個 Request 前後順序就會影響到最終接收到的結果不一樣,這就是 Race Condition。編程
Memory Leak 是最常被你們忽略的一點。緣由是在傳統網站開發中,咱們每次跳轉都是整個頁面從新加載,從新執行 JavaScript,因此不太須要關注內存的問題!可是當咱們但願將網站作得像軟件時,這件事就變得很重要。例如作 SPA (Single Page Application) 網站時,咱們是經過 JavaScript 來達到切換頁面的內容,這時若是有對 DOM 註冊監聽事件,而沒有在適當的時機把監聽的事件移除,就有可能形成 Memory Leak。好比說在 A 頁面監聽 body 的 scroll 事件,但頁面切換時,沒有把 scroll 的監聽事件移除。後端
當有異步行爲時,函數的狀態就會變得很是複雜!好比說咱們有一個付費用戶才能播放的視頻,首先可能要先獲取這部視頻的信息,接着咱們要在播放時去驗證使用者是否有權限播放,而使用者也有可能再按下播放後又當即按了取消,而這些都是異步執行,這時就有會各類複雜的狀態須要處理。bash
JavaScript的try/catch能夠捕捉同步的異常,但異步的程序就沒這麼容易,尤爲當咱們的異步行爲很複雜時,這個問題就越發明顯。dom
咱們除了要面對異步會遇到的各類問題外,還須要煩惱不少不一樣的API異步
上面列的API都是異步的,但他們都有各自的API及寫法!若是咱們使用RxJS,上面全部的API均可以經過RxJS來處理,就能用一樣的API操做(RxJS的API)。async
這裏咱們舉一個例子,假如咱們想要監聽點擊事件(click event),但點擊一次以後再也不監聽。函數
var handler = (e) => {
console.log(e);
document.body.removeEventListener('click', handler); // 結束監聽
}
// 註冊監聽
document.body.addEventListener('click', handler);
複製代碼
Rx.Observable
.fromEvent(document.body, 'click') // 註冊監聽
.take(1) // 只取一次
.subscribe(console.log);
複製代碼
大體上能看得出來咱們在使用RxJS後,不論是針對DOM Event仍是上面列的各類API咱們均可以經過RxJS的API來作數據操做,示例中用 take(n)來設定只取一次,以後就釋放內存。
說了這麼多,其實就是簡單一句話
RxJS是一套由Observable sequences來組合異步行爲和事件基礎函數的Library!
能夠把RxJS想成處理異步行爲的Lodash。
也能夠被稱爲Functional Reactive Programming,更切確地說是指Functional Programming及Reactive Programming兩個編程思想的結合。
RxJS確實是Functional Programming跟Reactive Programming的結合,但能不能稱爲Functional Reactive Programming(FRP)一直有爭議。
Rx在官網上特別指出,有時這會被稱爲FRP,但這實際上是個「誤稱」。
簡單說FRP是操做隨着時間連續性改變的數值,而Rx則比較像是操做隨着時間發出的離散數值,這個部份讀者不用分得太細,由於FRP的定義及解釋一直存在着歧異,也有衆多大神爲此爭論,以下
AndréStaltz: Rx著名的推廣者,也是RxJS 5主要貢獻者之一,同時是Cycle.js的做者。Staltz特別寫了一篇文章解釋爲何Rx不能說是FRP但他仍然稱其爲FRP。
Juan Gomez:曾在Netflix工做,目前任職於Fitbit,常常出如今國外演討會,主要寫Android。Juan Gomez在Droidcon NYC 2015的演講中特別提出他堅持稱Rx爲FRP。
Evan Czaplicki:任職於NoRedInk,Elm的做者。Evan在StrangeLoop 2014的演講中,特別爲如今各類FRP的不一樣解釋作分類。
Rx最先是由微軟開發的LinQ擴展出來的開源項目,以後主要由社區的工程師貢獻,有多種語言支持,也被許多科技公司所採用,如Netflix,Trello,Github,Airbnb…等。
Functional Reactive Programming是一種編程思想(programming paradigm),舉個例子,像OOP就是一種編程思想,OOP告訴咱們要使用對象的方式來思考問題,以及編寫程序。而Functional Reactive Programming其實涵蓋了Reactive Programming及Functional Programming兩種編程思想。
Functional Programming大部分的人應該多少都有接觸過,這也是Rx學習過程當中的重點之一,咱們以後會花兩章的篇幅來細講Functional Programming。若是要用一句話來總結Functional Programming,那就是用function來思考咱們的問題,以及撰寫程序
在下一篇文章會更深刻的講解Functional Programming
不少人一談到Reactive Programming就會直接聯想到是在講RxJS,但實際上Reactive Programming還是一種編程思想,在不一樣的場景都有機會遇到,而非只存在於RxJS,尤雨溪(Vue的做者)就曾在twitter對此表達不滿!
Reactive Programming簡單來講就是當變量或數據發生變化時,由變量或數據自動告訴我發生變更了
這句話看似簡單,其實背後隱含兩件事
當發生變更=>異步:不知道何時會發生變更,反正變更時要跟我說
由變量自動告知我=>不用通知個人每一步代碼
因爲最近很紅的Vue.js底層就是用Reactive Programming的概念實現,能很好的舉例,讓你們理解什麼是Reactive Programming!
當咱們在使用vue開發時,只要一有綁定的變量發生改變,相關的變量及頁面也會跟着變更,而開發者不須要寫這其中如何通知發生變化的每一步代碼,只須要專一在發生變化時要作什麼事,這就是典型的Reactive Programming(記得必須是由變量或數據主動告知!)
Vue.js在作two-ways data binding是經過ES5 definedProperty的getter/setter。每當變量發生變更時,就會執行getter/setter從而收集有改動的變量,這也被稱爲依賴收集。
Rx基本上就是上述的兩個觀念的結合,這個部份在看完以後的文章,會有更深的體悟。
今天這篇文章主要是帶你們瞭解爲何咱們須要RxJS,以及RxJS的基本介紹。若讀者還不太能吸取本文的內容,能夠過一段時間後再回來看這篇文章會有更深的體會,或是在下方留言給我!