初識RxJS

什麼是Rx.JS?

  Rx.JS是英文 Reactive Extensions for JavaScript 的縮寫.翻譯成中文就是:JavaScript的響應式擴展.其主要的功能就是利用響應式編程的模式來實現JavaScript的異步式編程.
  相對於JavaScript中其它的異步式解決方式(回調函數、Promise、Gender、async函數而言),Rx.JS有着更增強大的特性和更加優雅的寫法.如(純淨性、流動性、值)。html

Rx.JS的基本概念

  Rx.JS的響應式編程操做是結合了觀察者模式、迭代模式以及函數式編程來實現的.它主要有着以下幾個概念:前端

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

  下面,來讓咱們看一個簡單的示例.   咱們都知道,在前端開發當中爲性能的優化,咱們每每會對某個持續不斷會觸發的事件作一下事件節流.,也就是事件增長一個節流閥,以限制事件的不斷觸發.最多見的作法就是設定一個定時器.來進行判斷.事件在多少秒以內不斷觸發的話.就將節流閥打開.不進行事件操做.直達不斷觸發事件的行爲結束以後,才進行事件操做.最多見的就是輸入框的例子.以下面代碼所示:ajax

<input id="text"></input>
<script>
    var text = document.querySelector('#text'),
        timer = null,
        currentSearch = '';

    text.addEventListener('keyup', (e) =>{
        clearTimeout(timer)
        timer = setTimeout(() => {
            // 聲明一個當前所搜的狀態變量
            currentSearch = '書';

            var searchText = e.target.value;
            $.ajax({
                url: `search.qq.com/${searchText}`,
                success: data => {
                    // 判斷後臺返回的標誌與咱們存的當前搜索變量是否一致
                    if (data.search === currentSearch) {
                        // 渲染展現
                        render(data);
                    } else {
                        // ..
                    }
                }
            });
        },250)
    })
</script>
複製代碼

  上面的代碼就是一個很常見的一個事件節流的用法.當你按下鍵盤觸發事件時,並非直接發送AJAX請求.而是使用setTimeout延遲250毫秒.在延遲的過程當中若是有新的事件觸發.就會從新計算延遲.如此不斷的反覆.直到兩次觸發事件的間隔大於250毫秒.纔會真正的發送AJAX請求.編程

  下面讓咱們來看看上述的邏輯用RxJS怎樣的實現.數據結構

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .debounceTime(250)
  .subscribe(function(){
      $.ajax({
        url: `search.qq.com/${searchText}`,
        success: data => {
          // 判斷後臺返回的標誌與咱們存的當前搜索變量是否一致
          if (data.search === currentSearch) {
            // 渲染展現
            render(data);
          } else {
            // ..
          }
        }
    });
  });
複製代碼

  上面是用RxJS實現的一樣的功能.但咱們看到其代碼精簡了許多.上述代碼中首先獲取到一個button元素.而後使用Rx.Observable.fromEvent建立了一個被觀察對象.其對象所監聽的是button元素的.click事件.每當button元素的click事件觸發時.就會發射一個值出去.這個值途中通過debounceTime操做符,延時了250毫秒.而後再被觀察者對象捕獲.最終觸發其定義的AJAX事件.這就是上述代碼中的實現過程.
  然而咱們看到.雖然上述在定義執行的過程當中作了許多的事情,但這些是RxJS在內部幫助咱們就作好了的.咱們只須要它給咱們的API方法就能夠實現用幾段簡單的代碼,實現一段複雜的操做.併發

Observable (可觀察對象)

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

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

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() 函數主動關閉ObserverObservable的監聽訂閱.其使用方法以下:

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 在什麼樣的執行上下文中發送通知給它的觀察者。

上面是我最近學習RxJS時一些粗淺的總結,但願對你們有所幫助.若是文中有何不當之處請予以斧正,信息.

參考資料

個人我的網址: wangyiming.info

相關文章
相關標籤/搜索