淺析Angular之RxJS

本文結構:

  • 什么是RxJS
  • RxJS有什么特點
  • RxJS核心概念

什么是RxJS

在javaScript中,我們可能會經常接觸到類似于回調函數、Promise、Gender、async函數等異步編程方式,雖然以上的方式各有各的特點,但是我們需要更加強大的特性和更加優雅的寫法.因此RxJS便是我們更好的選擇.

Rx.JS是英文 Reactive Extensions for JavaScript 的縮寫.翻譯成中文就是: JavaScript的響應式擴展.其主要的功能就是利用響應式編程的模式來實現JavaScript的異步式編程.

RxJS有什么特點

根據官方文檔的介紹:

先寫個簡單的例子,注冊事件監聽器(事件代理):

var button = document.querySelector('button');
button.addEventListener('click', () => console.log('Clicked!'));

咱們用RxJS來實現這個功能(必須要引入Rxjs):

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .subscribe(() => console.log('Clicked!'));

以上代碼大家應該是能看懂的,大概解釋一下. Rx.Observable.fromEvent()相當于創建了一個可觀察對象Observable,也就是監聽的代理對象,subscribe是這個對象的一個方法,該方法返回這個監聽的事件,subscribe方法的參數是對觀察對象返回值做出下一步操作(回調函數).

接下來介紹RxJS的特點:

純凈性

先看反面例子:

var count = 0;
var button = document.querySelector('button');
button.addEventListener('click', () => console.log(`Clicked ${++count} times`));

count作為一個全局變量,污染了全局環境,把應用狀態搞的一團糟

下面是正面例子:

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .scan(count => count + 1, 0)
  .subscribe(count => console.log(`Clicked ${count} times`));

scan 操作符的工作原理與數組的 reduce 類似。
每次回調函數運行后的返回值會作為下次回調函數運行時的參數.

流動性 (Flow)

反面例子:

var count = 0;
var rate = 1000;
var lastClick = Date.now() - rate;
var button = document.querySelector('button');
button.addEventListener('click', () => {
  if (Date.now() - lastClick >= rate) {
    console.log(`Clicked ${++count} times`);
    lastClick = Date.now();
  }
});   //實現控制一秒鐘內最多點擊一次

正面教材:

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .throttleTime(1000)
  .scan(count => count + 1, 0)
  .subscribe(count => console.log(`Clicked ${count} times`));

這下覺得RxJS 用起來挺清爽的吧

RxJS核心概念
  • Observable (可觀察對象): 表示一個概念,這個概念是一個可調用的未來值或事件的集合。
  • Observer(觀察者): 一個回調函數的集合,它知道如何去監聽由 Observable 提供的值。
  • Subscription (訂閱): 表示 Observable 的執行,主要用于取消 Observable 的執行。
  • Operators (操作符): 采用函數式編程風格的純函數 (pure function),使用像 map、filter、
    concat、flatMap 等這樣的操作符來處理集合。
  • Subject (主體): 相當于 EventEmitter,并且是將值或事件多路推送給多個 Observer 的唯一方式。
  • Schedulers (調度器): 用來控制并發并且是中央集權的調度員,允許我們在發生計算時進行協調,例如 setTimeout 或 requestAnimationFrame 或其他。
Observable (可觀察對象)

Observables 是多個值的惰性推送集合

Observable是RxJS的核心概念之一.它實際上就是可以被外界觀察的一個對象.當本身的狀態發生變化時,就會將其變化推送給外界觀察它的對象,也就是 觀察者對象.同時因為Observables是多個值的惰性推送集合所以只有當使用一個觀察者對象去訂閱了它之后.它才會同步或異步地返回零到(有可能的)無限多個值.下面是使用RxJS創建一個Observable的方式

var observable = Rx.Observable.create(function subscribe(observer) {
  var id = setInterval(() => {
    observer.next('hi')
  }, 1000);
});

上面實例創建了一個 Observable,它每隔一秒會向觀察者發送字符串 'hi'.

Observer (觀察者)

什么是觀察者? - 觀察者是由 Observable 發送的值的消費者。觀察者只是一組回調函數的集合,每個回調函數對應一種 Observable 發送的通知類型:next、error 和 complete 。

簡單來說,Observer就是使用Observable發送出來值的一個方法集合.當一個Observable發送出來值之后由Observer來決定如何的去使用它.而使用的方式就是通過回調函數.將Observable發送出來的值作為參數傳入其中.讓后在內部去使用.同時根據Observable發送出來的值不同.其調用的回調函數也不同.分別有next(下一步),error(報錯),complete(結束).下面是使用Observer的方法:

observable.subscribe(observer);

要使用觀察者,需要把它提供給 Observable 的 subscribe 方法

Subscription (訂閱)

什么是 Subscription? Subscription 是表示可清理資源的對象,通常是 Observable 的執行。Subscription 有一個重要的方法,即 unsubscribe,它不需要任何參數,只是用來清理由 Subscription 占用的資源。在上一個版本的 RxJS 中,Subscription 叫做 "Disposable" (可清理對象)。
??Subscription(訂閱)是使用observable.subscribe()創建一個觀察者對象時.所返回的一個對象.它主要就是使用unsubscribe() 函數主動關閉Observer對Observable的監聽訂閱.其使用方法如下:

var observable = Rx.Observable.interval(1000);
var subscription = observable.subscribe(x => console.log(x));
// 稍后:
// 這會取消正在進行中的 Observable 執行
// Observable 執行是通過使用觀察者調用 subscribe 方法啟動的
subscription.unsubscribe();
Operators (操作符)

操作符是 Observable 類型上的方法,比如.map(...)、.filter(...)、.merge(...),等等。當操作符被調用時,它們不會改變已經存在的Observable實例。相反,它們返回一個新的 Observable ,它的 subscription 邏輯基于第一個 Observable

操作符是函數,它基于當前的 Observable 創建一個新的 Observable。這是一個無副作用的操作:前面的 Observable 保持不變。

就本質上而言Operators就是一個純粹的函數.它可以接收一個 Observable 作為輸入.并在經過內部的一系列處理后返回一個新的Observable作為輸出.流向下一個操作.

Subject (主體)

什么是 Subject? - RxJS Subject 是一種特殊類型的 Observable,它允許將值多播給多個觀察者,所以 Subject 是多播的,而普通的Observables是單播的(每個已訂閱的觀察者都擁有 Observable 的獨立執行)。

   `Subject` 像是 `Observalbe`,但是可以多播給多個觀察者。`Subject` 還像是` EventEmitters`,維護著多個監聽器的注冊表。

每一個Subject都同時是一個ObservableObserver.對于Subject你可以使用subscribe方法并指定一個觀察者.也可以調用next(v)、error(e)complete()來處理接受道到值.示例如下:

var subject = new Rx.Subject();

subject.subscribe({
  next: (v) => console.log('observerA: ' + v)
});
subject.subscribe({
  next: (v) => console.log('observerB: ' + v)
});

subject.next(1);
subject.next(2);

在上面的示例中,我們為 Subject 添加了兩個觀察者,然后給 Subject 提供一些值

Schedulers (調度器)

什么是調度器? - 調度器控制著何時啟動 subscription 和何時發送通知。它由三部分組成:

  • 調度器是一種數據結構。 它知道如何根據優先級或其他標準來存儲任務和將任務進行排序。
  • 調度器是執行上下文。 它表示在何時何地執行任務(舉例來說,立即的,或另一種回調函數機制(比如 setTimeout 或 process.nextTick),或動畫幀)。
  • 調度器有一個(虛擬的)時鐘。 調度器功能通過它的 getter 方法 now() 提供了“時間”的概念。在具體調度器上安排的任務將嚴格遵循該時鐘所表示的時間。
    調度器可以讓你規定 Observable 在什么樣的執行上下文中發送通知給它的觀察者。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容

  • 介紹 RxJS是一個異步編程的庫,同時它通過observable序列來實現基于事件的編程。它提供了一個核心的類型:...
    泓滎閱讀 16,626評論 0 12
  • 一.背景介紹 Rx(Reactive Extension -- 響應式擴展 http://reactivex.io...
    愛上Shu的小刺猬閱讀 2,061評論 1 3
  • title: RxJS簡介date: 2017-08-01 09:45:33tags: [JavaScript, ...
    color_cat閱讀 311評論 0 0
  • 作者寄語 很久之前就想寫一個專題,專寫Android開發框架,專題的名字叫 XXX 從入門到放棄 ,沉淀了這么久,...
    戴定康閱讀 7,643評論 13 85
  • "還記得年少時的夢嗎 像朵永遠不凋零的花 陪我經過那風吹雨打 看世事無常 看滄桑變化 那些為愛所付出的代價 是永遠...
    老虎凱閱讀 375評論 2 1