RxJS系列教程(二) 什么是RxJS?

RxJS可以解決的問題
  • 我們知道傳統(tǒng)的for,while對(duì)循環(huán)體中的異步程序是無(wú)法感知的,或者說(shuō),它們不會(huì)等待異步程序執(zhí)行完畢再進(jìn)入下一輪循環(huán)。
  • 錯(cuò)誤處理是任何程序都要解決的問題,本身就已很復(fù)雜的回調(diào)函數(shù)中再嵌入try/catch塊嗎?如果還想加入重試機(jī)制呢?
  • 商業(yè)邏輯內(nèi)嵌在回調(diào)函數(shù)中,可讀性差,復(fù)雜度高。現(xiàn)如今流行的組件化編程,即可重用,又可解耦,還方便測(cè)試;
  • 閉包是強(qiáng)大的,過度地使用閉包將導(dǎo)致我們不得不謹(jǐn)慎地審視變量的作用域以及其值。再加上共享變量帶來(lái)的副作用,混雜在if/else條件語(yǔ)句和for循環(huán)中,每天都會(huì)有修不完的bug;
  • 根據(jù)事件或耗時(shí)操作無(wú)響應(yīng)的時(shí)間進(jìn)行取消操作;
  • 自己實(shí)現(xiàn)throttling和debouncing是很困難的(二者區(qū)別見http://www.lxweimin.com/p/e91775195608)
  • 眾所周知的事件監(jiān)聽?zhēng)?lái)的內(nèi)存泄露問題;

RxJS可以優(yōu)雅地替代callback,或者基于promises的任何第三方庫(kù),使我們可以使用一個(gè)編程模型來(lái)對(duì)待任何數(shù)據(jù)源(除了遠(yuǎn)程http請(qǐng)求,Node.js中的Event Emitter也使用的是回調(diào)機(jī)制)。也就是說(shuō),我們可以用RxJS來(lái)處理讀取文件,http請(qǐng)求,鼠標(biāo)點(diǎn)擊,鼠標(biāo)移動(dòng)這些事件。

數(shù)據(jù)的流動(dòng)和傳播

事件必然伴隨著數(shù)據(jù)的產(chǎn)生,在響應(yīng)式編程的世界中,我們把任何可以被使用的數(shù)據(jù)源統(tǒng)稱為流(Stream)。我們?cè)賮?lái)看一下什么是響應(yīng)式編程模型:

var x = 1;
var y = 2;
var z = x + y; // z = ?

x = 2; // z = ?

顯而易見,z第一次出現(xiàn)時(shí)的值是3,當(dāng)x重新被賦值為2時(shí),z的值是多少?顯而易見,z沒有變化,因?yàn)閍的變化不會(huì)引起z的變化。我們可以說(shuō)這種變化沒有被傳播開來(lái)。因此我們可以說(shuō),響應(yīng)式編程是圍繞數(shù)據(jù)的流動(dòng)和傳播的,某個(gè)變量的變化會(huì)導(dǎo)致其他變量的變化。RxJS就是用Javascript實(shí)現(xiàn)的響應(yīng)式編程。

RxJS官網(wǎng):https://github.com/ReactiveX/rxjs

reactive官網(wǎng):http://reactivex.io/

pipeline

pipeline的中文意思是管道,很形象。在管道里是一個(gè)接一個(gè)的函數(shù),管道的左邊接到Stream上,即數(shù)據(jù)源,數(shù)據(jù)將會(huì)流經(jīng)管道,并按順序作為參數(shù)傳遞給每一個(gè)函數(shù)。管道的右邊連接著的是最終使用數(shù)據(jù)的程序,我們稱之為數(shù)據(jù)消費(fèi)者。

萬(wàn)物皆stream

就像面向?qū)ο笾腥f(wàn)物皆對(duì)象一樣,在RxJS中,不管是單個(gè)值,字節(jié)流還是從http請(qǐng)求獲取來(lái)的值,都是stream。比如,假設(shè)在RxJS中我們有叫做Stream的數(shù)據(jù)類型,我們創(chuàng)建了一個(gè)單個(gè)值的數(shù)據(jù)源:

Stream(2017);

這個(gè)時(shí)刻,它僅僅是個(gè)數(shù)據(jù)源,什么行為也沒有發(fā)生,如果想讓它運(yùn)作起來(lái),我們得需要消費(fèi)者或者叫做觀察者。通過消費(fèi)者的訂閱行為,數(shù)據(jù)源中的數(shù)據(jù)才開始真正流動(dòng)起來(lái)。因此我們可以知道stream這個(gè)數(shù)據(jù)類型是惰性求值的,不像promises,一旦創(chuàng)建即開始運(yùn)行。下面看看如果訂閱它讓它流動(dòng)起來(lái):

Stream(2017).subscribe(
  result => {
    console.log(result);
  }
);

subscribe函數(shù)中的箭頭函數(shù)即消費(fèi)者,當(dāng)消費(fèi)者一接收到數(shù)據(jù),stream就結(jié)束了。

有管道的例子:

Stream(1, 2, 3, 4)
  .filter(val => (val % 2) === 0)
  .map(val => val * val)
  .subscribe(
    result => {
      console.log(result);
    }
  );

filter和map即管道中的函數(shù),它們中的val參數(shù)即從stream中流出的數(shù)據(jù)。它們一起組成了pipeline。

RxJS中的組件
  • 生產(chǎn)者:在RxJS中的生產(chǎn)者叫做Observables。Observables負(fù)責(zé)推送事件,但不處理事件;

  • 消費(fèi)者:在RxJS中的消費(fèi)者叫做Observer。

    數(shù)據(jù)只會(huì)從生產(chǎn)者流向消費(fèi)者

  • 管道:在RxJS中,管道中的一個(gè)一個(gè)函數(shù)叫做observable operators,簡(jiǎn)稱operators。

  • 時(shí)間:我們知道異步程序不容易處理的背后實(shí)質(zhì)就是時(shí)間問題,RxJS是面向異步編程的解決方案,因此時(shí)間遍布于RxJS中的每一個(gè)角落。目前為止,我們只需要了解時(shí)間在RxJS中不是恒定的,產(chǎn)生事件的快慢與否取決于我們的需求。當(dāng)然,RxJS給了我們解決方案。

響應(yīng)式編程范式與其他編程范式

面向?qū)ο缶幊桃?code>狀態(tài)為中心,函數(shù)式編程以行為為中心,而響應(yīng)式編程則需要我們把數(shù)據(jù)看做是改變并流動(dòng)著的。在這里我想說(shuō)的是,RxJS可以很好的和其他范式配合起來(lái)使用。我們可以用面向?qū)ο蠓妒絹?lái)構(gòu)建我們的模型,用函數(shù)式編程和響應(yīng)式編程來(lái)構(gòu)建行為和處理事件。

在面向?qū)ο缶幊讨校瑺顟B(tài)是保存在變量或者集合對(duì)象里的。而響應(yīng)式編程中的狀態(tài)是短暫的、瞬間的,也就是說(shuō)在Rx中是永遠(yuǎn)不保留狀態(tài)的。

面向?qū)ο缶幊淌堑湫偷拿钍骄幊蹋憫?yīng)式編程則鼓勵(lì)我們寫聲明式的程序,也就是表達(dá)做什么,而不是表達(dá)怎么做。RxJS從函數(shù)式編程中借鑒了這一點(diǎn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,948評(píng)論 18 139
  • FRP是異步數(shù)據(jù)流編程 這不是什么新鮮的東西了。在前端編程中(用Javascript),監(jiān)聽某個(gè)按鈕的點(diǎn)擊事件,并...
    superYang0033閱讀 2,150評(píng)論 1 8
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,349評(píng)論 25 708
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位,與響應(yīng)式編程作為結(jié)合使用的,對(duì)什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,890評(píng)論 0 10
  • 這是個(gè)真理的集市 從早晨到黑夜 車馬與行人。 我?guī)е蓡杹?lái) (這的確是個(gè)欲望) 沒有指南與建議 自尊與生命 (這就...
    心種閱讀 190評(píng)論 1 1