原文連接:Understanding rxjs Subjects
原文做者:Luuk Gruijs;發表於2018年4月17日
譯者:yk;如需轉載,請註明出處,謝謝合做!javascript
RxJS 是真的好用,它能夠幫助咱們更好地編輯/訂閱數據流。雖然單用 Observable(可觀察對象)就能夠作不少事情,但 RxJS 仍是提供了多種用於操控數據流的類,Subject(主題)就是其中之一。java
若是你還不知道 Observable 是什麼的話,建議先讀讀個人另外一篇文章:Understanding, creating and subscribing to observables in Angular。若是你以爲你明白 Observable 是什麼意思,那行咱繼續!git
攝影:Anvesh Uppunuthula,來自 Unsplashgithub
Subject 就比如 Observable。你能夠訂閱它,就像你平時訂閱 Observable 同樣。它也有相似 next()
,error()
以及 complete()
的方法,就像你平時傳給 Observable 構造函數的 observer(觀察者)同樣。api
使用 Subject 主要是爲了多播(multicast)。Observable 默認是單播(unicast)的,而單播就意味着:對於每一個訂閱者,都只有一個獨立的 Observable execution 與之對應。證實以下:app
import * as Rx from "rxjs";
const observable = Rx.Observable.create((observer) => {
observer.next(Math.random());
});
// 訂閱者甲
observable.subscribe((data) => {
console.log(data); // 0.24957144215097515 (隨機數)
});
// 訂閱者乙
observable.subscribe((data) => {
console.log(data); // 0.004617340049055896 (隨機數)
});
複製代碼
因爲 Observable 在設計上就是單播的,因此若是你但願使多個訂閱者收到相同的數據,那麼用 Observable 可能會很是麻煩。而 Subject 能夠幫助咱們解決這個問題。正如先前所說,Subject 能夠用來實現多播。多播的基本含義是:一個 Observable execution 能夠在多個訂閱者之間共享。dom
譯者注:每當咱們調用一次
Observable.subscribe()
時,一個新的 Observable execution 就會被啓動。詳見 Observable。函數
Subject 也可比做事件發射器(EventEmitter),其中註冊了多個事件監聽器。 當咱們訂閱 Subject 時,它並不會啓動一個新的 execution 來傳送數據。而是在現有觀察者列表中註冊一個新的觀察者,僅此而已。ui
多播是 Subject 的特性,使用 Subject 便可實現多播,無需任何技巧。下面是一個簡單的示例:spa
import * as Rx from "rxjs";
const subject = new Rx.Subject();
// 訂閱者 1
subject.subscribe((data) => {
console.log(data); // 0.24957144215097515 (隨機數)
});
// 訂閱者 2
subject.subscribe((data) => {
console.log(data); // 0.24957144215097515 (隨機數)
});
subject.next(Math.random());
複製代碼
奶思!咱們使兩個訂閱者得到了相同的數據。然而,這並不是 Subject 的惟一用途。
相比 Observable 只能做爲數據的生產者,Subject 便可以做爲生產者,也能夠做爲消費者。經過把 Subject 做爲消費者使用,你能夠將一個單播 Observable 轉換爲多播。示例以下:
import * as Rx from "rxjs";
const observable = Rx.Observable.create((observer) => {
observer.next(Math.random());
});
const subject = new Rx.Subject();
// 訂閱者 1
subject.subscribe((data) => {
console.log(data); // 0.24957144215097515 (隨機數)
});
// 訂閱者 2
subject.subscribe((data) => {
console.log(data); // 0.24957144215097515 (隨機數)
});
observable.subscribe(subject);
複製代碼
將咱們的 subject 傳遞給 subscribe()
,使其接收由 observable 傳來的值(消費數據)。隨後,subject 的全部訂閱者都會當即收到這個值。
若是你但願 Observable 的多個訂閱者接收到相同的數據,那就用 Subject 來代替 Observable。因爲其 Observable execution 能夠在多個訂閱者之間共享,因此 Subject 將確保每一個訂閱者接收到的數據是絕對相等的。另外,Subject 還有幾種變體,我將在下一篇文章中詳細描述它們之間的區別。
譯者注:後面都是一些可有可無的招聘信息,我就不翻譯了,除非你真的想去阿姆斯特丹。