天天看點

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

1. 介紹

RxJS 是什麼?用一句話類概括就是:RxJS 是用于 JavaScript 的ReactiveX 庫,它是一個可以通過觀察序列變化,掌握非同步事件處理的利器。

在學習 RxJS 之前我們首先需要了解以下的前提知識:

  • Reactive Extensions(Rx)

    是一個使用可觀察序列和 LINQ 樣式查詢運算符組成異步和基于事件的程式的庫。

  • ReactiveX

    是 observer 模式、lterator 模式和函數式程式設計的最佳思想的組合。

  • Reactive Programming(反應式程式設計)

    是用異步資料流程式設計。

  • Streams

    流——便宜又無處不在,什麼都可以是一股流。比如變量、使用者輸入、屬性、緩存、資料結構都可以被稱為流。

    舉一個程式化的例子來說,假如現在有一個觀察者訂閱了 click 事件,當有使用者在頁面上點選滑鼠時,每一次點選都會觸發一次 click 事件,并發送 click 事件資料(Mouse Event)給觀察者,當使用者連續點選多次,觀察者就會收到一系列的事件資料,我們把這一系列的事件資料就叫做一個流(Stream)。

    再舉一個非同步事件的例子,我們通過某非同步事件,向服務端發送 Ajax 請求,然後從服務端得到響應資料,在這個過程中,可能會持續地發出多個 Ajax 請求,并且響應資料會不同時間、不同順序地傳回用戶端。類似這樣的過程,就是串流的概念。

在非同步事件中,由于事件響應的時間不确定、順序不确定,JavaScript 在處理非同步事件時,會有一定的困難,很容易出現 bug,而 RxJS 可以輕松幫我們處理這樣的非同步事件。

總結來說,使用 RxJS 的目的就是,有效管理非同步環境下的事件資料。

我們知道 RxJS 是一組可用來處理非同步或事件的 JavaScript 函式庫,那麼非同步或事件的種類有哪些呢?

  • 非同步

    Ajax/XHR/fetch API

    Service Worker/Node Stream

    setTimeout/setInterval

    Promise

  • 事件

    各種 Dom 事件(click/dbclick/keyup/mousemove……)

    CSS 動畫事件(CSS3 transitionEnd event)

    HTML5 Geolocation/WebSockets……

2. 核心概念

  • Observable 可觀察的物件

    代表一組未來即将産生的事件資料(被觀察的物件)。從上面舉的例子中來說,click 事件就是一個 Observable,也就是說當 click 事件被觸發的時候,它會發出一些事件資料(Stream)給觀察者。

  • Observer 觀察者

    代表一個用來接收觀察結果的物件(Observer 收到的就是事件資料,也就是 Stream)。

  • Subscription 訂閱

    表示 Observable 的執行,主要用于取消訂閱。

  • Operator 運算符

    用來處理一系列的事件資料集合,可以了解成 Operator 會通過一系列的過濾、篩選等操作,對 Observable 進行處理,最終将事件資料送給觀察者。

    常見的運算符包括:map/filter/concat/flatMap……

  • Subject 主體物件

    主要用來廣播收到的事件資料給多位 Observer。

  • Scheduler 排程控制器

    用來集中管理和排程多重事件之間的資料,以控制事件并發情況。

3. 基本運作過程

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

上面這段代碼的意思是,通過 RxJS 去使用建立運算符(Creation)的 API(interval) 建立一個 Observable,這個 Observable 會每 0.5s 發出一個數字(從 0 開始)。然後通過 pipe(中文是水管的意思,可以結合流的概念來了解)中的過濾運算符 take ,隻發送前四筆資料給觀察者。觀察者(console.log)通過 subscribe 去訂閱到 Observable 發送的資料。

上面的代碼運作結果如下:

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

在上面提到的核心概念中,有提到 Subscription 這一概念,在這裡可以舉個例子幫助我們加深了解。現在我們将上面代碼中通過 take 方法隻取前 4 筆資料,改為取前 40 筆資料,并且将觀察結果存在 subs 中,這裡的 subs 也就是我們所說的 Subscription。最後在通過 subs 調用 unsubscribe 方法取消觀察者和可觀察物件的訂閱關系,也即不再接受可觀察物件發來的訂閱資料。

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

上邊那段代碼還可以利用 ES5 解構指派來精簡一下寫法:

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

也可以通過 ES Module 來精簡代碼:

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

上面是 RxJS 基本的運作過程,那代碼怎麼寫呢?

  1. 建立可觀察的 Observable 物件
  2. 建立觀察者 Observer 物件
  3. 建立訂閱物件(訂閱 Observable 物件,并傳入 Observer 觀察者物件)
  4. 取消訂閱 Subscription 物件

上面的代碼運作結果就是,每當在頁面 document 範圍内點選滑鼠時,控制台就會列印一次 MouseEvent 事件。這裡需要注意一點的是,必須有觀察者訂閱 Observable,Observable 發生的事件才會被觸發,沒有訂閱的觀察者,Observable 就不會産生任何事件資料。

上面是語義清晰的一種寫法,下面是一種簡易的寫法:

  1. 建立可觀察的 Observable 物件
  2. 建立訂閱物件(訂閱 Observable 物件,并自動建立觀察者物件)
  3. 取消訂閱 Subscription 物件

4. RxJS 如何通過運算符過濾資料

現在我想要訂閱 click 事件,并且傳回 ClientX 小于 1000 的所有事件,代碼如下:

  1. 建立可觀察的 Observable 物件
  2. 套用 filter 運算符
    const { filter } = rxjs.operators;
    clicks$ = clicks$.pipe(filter(x => x.clientX <1000));
               
  3. 建立訂閱物件(訂閱 Observable 物件,并自動建立觀察者物件)
  4. 取消訂閱 Subscription 物件

假如現在我隻需要傳回 ClientX 小于 1000 的所有事件中的前四筆資料,我們需要對運算符部分的操作進行更改:

var subs = clicks$.pipe(
    filter(x => x.clientX <1000),
    take(4)
).subscribe((x) => console.log(x));
           

這裡需要注意的是,隻有符合條件的資料流能夠被列印出來,并且一但 take 運算符一旦收集夠四個事件之後,就會自動執行取消訂閱的操作。

5. RxJS 主體物件(Subject)的用法

  1. 建立主體物件(Subject,之後要靠這個主體物件進行廣播)
  2. 建立可觀察的 Observable 物件
  3. 設定最多取得兩個事件資料就将 Observable 物件設為完成
  4. 設定将 clicks$ 全部交由 subject 主體物件進行廣播
  5. 最後再由 subject 去建立 Observer 觀察者物件
    var subs1$ = subject.subscribe((x) => console.log(x.clientX));
    var subs2$ = subject.subscribe((x) => console.log(x.clientX));
               
  6. 取消訂閱 Subscription 物件
    subs1$.unsubscribe();
    subs2$.unsubscribe();
               

通過 Subscription 事件資料隻需要發送一次給 subject 就完成了,而不需要分别發送兩次給 subs1$ 和 subs2$。

6. 彈珠圖

彈珠圖可以很好的描述 RxJS 中操作運算符的運算過程。

  • take
    RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
  • map
    RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
  • concat
    RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

在這個網站可以看到更多彈珠圖。

在這個網站還可以看到以動畫呈現的彈珠圖

7. 如何選擇運算符

RxJS 的運算符衆多,有時候不知道選擇哪一個更有效,這時候可以在這個網站通過互動式的問答,選擇出合适的運算符。

運算符的分類:

RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符
RxJS新手入門1. 介紹2. 核心概念3. 基本運作過程4. RxJS 如何通過運算符過濾資料5. RxJS 主體物件(Subject)的用法6. 彈珠圖7. 如何選擇運算符

本篇文章整理自b站視訊一小時 RxJS 入門

繼續閱讀