出處:https://www.cnblogs.com/forcheng/p/13433371.html
1. 前言RxJS 是一個庫,它透過使用 observable (可觀察物件)序列來編寫非同步和基於事件的程式。其結合了 觀察者模式 、 迭代器模式 和 使用集合的函數語言程式設計 ,以一種理想方式來管理事件序列所需要的一切。
本文將主要探討觀察者模式、迭代器模式以及它們如何在 RxJS 中被應用。
2. 觀察者模式實現了生產者(事件的建立者)和消費者(事件的監聽者)的邏輯分離關係。
瀏覽器 DOM 事件的監聽和觸發應該是 Web 前端最典型的觀察者模式的實現。
document.body.addEventListener('click', function listener(e) { console.log(e);});document.body.click(); // 模擬使用者點選
監聽:透過 addEventListener 給 document.body 節點繫結一個 click 事件的事件處理函式。
關係圖如下:
3. 迭代器模式可以讓使用者透過特定的介面訪問集合中的每一個元素而不用瞭解底層的實現。
從 ES 6 開始,引入的一種新的遍歷機制—— 迭代器 ,其就是迭代器模式在 JavaScript 中的一種實現。在 JavaScript 中,迭代器是一個物件,它定義一個序列,並在終止時可能返回一個返回值。 更具體地說,迭代器是透過使用 next() 方法實現 Iterator protocol (迭代器協議)的任何一個物件,該方法返回具有兩個屬性的物件: value 和 done ,其中 value 代表具體返回值, done 表示是否已經迭代完畢。
String 、 Array 、 Map 和 Set 等都是內建可迭代物件,它們的原型物件都擁有一個 Symbol.iterator 方法。
const arr = ['a', 'b'];const iterator = arr[Symbol.iterator](); // 獲取迭代器物件iterator.next(); // { value: 'a', done: false }iterator.next(); // { value: 'b', done: false }iterator.next(); // { value: undefined, done: true }
我們常常用 for-of 迴圈來遍歷可迭代物件:
const arr = ['a', 'b'];for (let value of arr) { console.log(value); // a b}
for-of 語法是為了方便遍歷可迭代物件,其內部實現呼叫的是 Symbol.iterator 方法,類似下面的程式碼:
const arr = ['a', 'b'];const iterator = arr[Symbol.iterator]();let result = iterator.next();while (!result.done) { console.log(result.value); // a b result = iterator.next();}
迭代器的特點:
訪問集合中的內容而不用瞭解底層的實現。提供了一個統一的介面遍歷不同的集合結構,從而支援同樣的演算法在不同的集合結構上進行操作。4. RxJS 中兩種模式的結合和實現RxJS 中包含兩個基本概念:**Observable **和 Observer 。
Observable作為可觀察物件(被觀察者),是一個可呼叫的未來值或事件的集合(非同步或同步資料流)。
Observer作為觀察者,是一個回撥函式的集合,它知道如何去監聽由 Observable 提供的值。
Observable 和 Observer 之間的訂閱釋出關係(觀察者模式)如下:
訂閱: Observer 透過 Observable 提供的 subscribe() 方法訂閱 Observable 。
釋出: Observable 透過 Observer 提供的 next 方法向 Observer 釋出事件。
兩者關係的虛擬碼如下:
// Observerconst observer = { next(value) { console.log(value); }};// Observablefunction Observable (observer) { setTimeout(()=>{ observer.next('A'); }, 1000);}// subscribeObservable(observer);
從上可知,所謂訂閱,就是將觀察者 Observer 注入到可觀察物件 Observable 中。
在 RxJS 中, Observer 除了有 next 方法來接收 Observable 的事件外,還提供了另外的兩個方法: error() 和 complete() ,來處理異常和完成狀態。
const observer = { next(value) { /* 處理值 */ }, error(err) { /* 處理異常 */ }, complete() { /* 處理已完成態 */ }};
結合 迭代器 Iterator 來理解 Observer 的三個方法:
next() : Observer 透過提供 next 方法來接受 Observable 流(集合),是一種 push 形式(推送)。對比 Iterator ,則是透過呼叫 iterator.next() 拿值,是一種 pull 的形式(拉取)。complete() :當不再有新的值發出時,將觸發 Observer 的 complete 方法。對比 Iterator ,則是在 next() 的返回結果中的 done 為 true 時,則表示 complete 。error() :當處理事件中出現異常時,透過 try-catch 捕獲異常, Observer 提供 error 方法來接收錯誤進行統一處理。一個簡單的 RxJS 訂閱-釋出例項:
import { Observable } from 'rxjs';const observable = new Observable(function (observer) { // 通知觀察者 observer.next('a'); observer.next('b'); observer.complete(); // 將取消該觀察者的訂閱 // observer.error(new Error('err')); observer.next('c'); // 由於已經 complete,所以不會再發送});// 定義觀察者,next、complete、error 方法處理流的不同狀態const observer = { next: (value) => console.log(value), error: err => console.error('Observer got an error: ' + err), complete: () => console.log('Observer got a complete notification')}// 訂閱 Observable 並執行const subscription = observable.subscribe(observer); // 將返回一個可取消的訂閱物件 subscription
執行結果:
ab
5. 小結
**一句話概述 RxJS 中實現的觀察者+迭代器模式:**就是將觀察者 Observer 注入到可觀察物件 Observable 中,然後在可觀察物件 Observable 中透過呼叫 Observer 提供的 next 、 complete 、 error 方法處理流的不同狀態,以實現對資料流的一種順序訪問處理。
6. 參考RxJS 中文文件
Rx.js實現原理淺析
出處:https://www.cnblogs.com/forcheng/p/13433371.html