Observable - 觀察者模式的理解

weixin_34107955發表於2017-12-01

建立一個Observable的程式碼

const hello = Rx.Observable.create(function(observer) {
   observer.next('Hello');
   observer.next('World');
});
  • create傳入的引數為一個subscriber函式,該函式有一個引數為observer,observer是一個觀察者物件,該物件有三個屬性,屬性值為函式。如下:
var observer = {
  next: x => console.log('Observer got a next value: ' + x),
  error: err => console.error('Observer got an error: ' + err),
  complete: () => console.log('Observer got a complete notification'),
};
  • 當observable被訂閱的時候,即observable.subscribe(function next(x), function error(x), function complete(x)), 建立該observable時傳入的回撥函式即被執行,observer呼叫next方法,並傳入引數(即發射值),發射出去的值則作為subscribe中回撥函式的引數,即傳入function next(x)中的x,並執行該回撥函式。 自此只要被觀察者發生了變化,就會呼叫create的回撥函式將變化的值通知觀察者,並執行對應observer的next()方法。

Observable - 被觀察者
Observable.subscribe(observer) - 對被觀察者進行訂閱
Observer - 觀察者
建立被觀察者時,傳入一個訂閱函式,當觀察者對被觀察者進行訂閱時,就呼叫這個訂閱函式,訂閱函式的作用是向觀察者發射資料,通知資料(流)的變化。觀察者根據發射過來的不同資料,自行處理對應處理函式裡的邏輯。

原始碼

看看原始碼做了什麼:

建立Observable的過程:

(1) 將create()的引數(一個匿名函式function(observer){})作為引數傳入建構函式,並儲存該匿名函式到類變數this._subscribe。

Observable.create = function (subscribe) {
        return new Observable(subscribe);
    };
    return Observable;

function Observable(subscribe) {
        this._isScalar = false;
        if (subscribe) {
            this._subscribe = subscribe;
        }
呼叫observable.subscribe的過程:

(1) 將subscribe()裡的回撥函式傳入。
(2) 通過toSubscriber_1.toSubscriber包裝成一個Subsciber物件即下文中的sink。該物件有一些屬性,其中包括next, error, complete屬性分別指向subscribe中對應的回撥函式。並通過this._subscribe(sink),將sink傳值給Rx.Observable.create(function(observer) {..})中的observer引數。
(3) 通過this._subscribe(sink)呼叫了create()裡的回撥函式即function(observer) { observer.next('Hello');},並執行對應的next()函式,並傳入對應的引數。

Observable.prototype.subscribe = function (observerOrNext, error, complete) {
        var operator = this.operator;
        var sink = toSubscriber_1.toSubscriber(observerOrNext, error, complete);
        if (operator) {
            operator.call(sink, this.source);
        }
        else {
            sink.add(this.source ? this._subscribe(sink) : this._trySubscribe(sink));
        }
        if (sink.syncErrorThrowable) {
            sink.syncErrorThrowable = false;
            if (sink.syncErrorThrown) {
                throw sink.syncErrorValue;
            }
        }
        return sink;
    };
Observable.prototype._trySubscribe = function (sink) {
        try {
            return this._subscribe(sink);
        }
        catch (err) {
            sink.syncErrorThrown = true;
            sink.syncErrorValue = err;
            sink.error(err);
        }
    };

相關文章