rxjs 學習(1)-認識 rxjs 和理解 observables

什麼是 rxjs?

我查閱了一些資料,以爲比較通俗易懂的說法是:rxjs 是一個使用 Observable 的響應式編程庫。它經過使用 observable 序列編寫基於異步和事件的程序。核心類型是: Observable , 附屬類型:Observer, Schedules, Subjects 和一些操做符 map,filter等。這些操做符能夠把異步事件看成集合處理。咱們能夠把rxjs 看成用來處理事件的 lodash;javascript

lodash 是一個一致性、模塊化、高性能的 js 實用工具庫,它的內部封裝了不少字符串,數組,對象等常見類型的函數。java

如何理解 Observable?

說到 Observable,可能咱們得先了解一下異步編程的歷史。ajax

  • 最開始的時候,採用的是 callback 回調的方式,註冊回調函數,等異步請求返回會後,把數據傳入回調函數,對異步請求的結果進行處理。可是若是出現多個異步嵌套,就會出現可怕的回調地獄。
  • promise 的出現緩解了「callback hell」的問題。它承諾在必定的時間內,會完成事件或者是拋出錯誤。在代碼執行時只須要監聽這兩種狀態就能夠了。可是也有弊端,同步和異步代碼分離很差,代碼可讀性查,而且它一次只能處理一個事件,隨着程序變大,promise 也會變得很是難管理。
  • 最新的 es2017 中出現了 async/await 的寫法,它並非一個新的功能,能夠看做是 promise 的語法糖。可是依然沒有改變同步代碼和異步代碼混用的局面。

對於數據傳輸的更具體地敘述可見:編程

此時 Observable 這種響應式的把同步異步代碼都看成異步來操做的響應式編程就產生了。數組

rxjs 中的 Observable,說通俗一點,就是一個數據或是不少個事件組成在一塊兒的數據流。rxjs 提供了不少操做這些數據流的方法,那就是操做數,好比 map,filter等。 如今咱們來初步瞭解一下 Observable 吧。promise

關於 rxjs 的基礎知識

既然上面說到了 Observable 是 rxjs 的核心類型,因此咱們就來好好了解一下 observable 吧。異步

Observables 的產生來源

Observable 是數據流,它的產生有兩種,一種是來自於已有的數據,將其轉換成 observable; 還有一種是從無到有,直接建立 observable。這種感受就像:我想要送給朋友一件禮物,能夠選擇本身手動 DIY, 也能夠到淘寶買一份,而後包裝。async

從別的數據轉換過來的方式有:模塊化

  • 來自一個或多個值,能夠直接用 of(value) 轉化: Rx.Observable.of('haha','xixi');
  • 來自數組, 使用 from(array) 轉換: Rx.Observable.from([1,2,3]);
  • 來自事件, 使用 fromEvent(element,event) 轉換: Rx.Observable.fromEvent(document.querySelector('button'), 'click');
  • 來自 Promise, 使用 fromPromise() 轉換:Rx.Observable.fromPromise(fetch('/users'));
  • 來自 callback,bindCallback():Rx.Observable.bindCallback(fs.exists);

本身建立 observables 的有:異步編程

  1. 在外部產生新事件
import { Observable, BehaviorSubject, Subject } from 'rxjs';
const myObservable = new Subject();
myObservable.subscribe(value => console.log(value));
myObservable.next('haha');
  1. 在內部產生新事件
var myObservable = Rx.Observable.create(observer => {
  observer.next('haha');
  setTimeout(() => observer.next('xixi'), 1000);
});
myObservable.subscribe(value => console.log(value));

選擇哪一種方式須要根據場景。當你想要包裝隨時間推移產生值的功能時,普通的 Observable 就已經很好了。使用 Subject,你能夠從任何地方觸發新事件,而且將已存在的 observables 和它進行鏈接。

控制 Observables 數據流的流動過程

以在 input 框中輸入 "hello world」 爲例

const input = Rx.Observable.fromEvent(document.querySelector('input','input'));
  • 過濾掉小於3個字符長目標值
input.filter(event => event.target.value.length > 2)
    .map(event => event.target.value)
    .subscribe(value => console.log(value))// "hel"
  • 延遲事件
input.delay(200)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));
  • 中止輸入後 200ms 方能經過最新的那個事件
input.debounceTime(200)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));
  • 取前 3 次事件流,在3次事件流後中止事件流
input.take(3)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));// hel
  • 直到其餘 observable 觸發事件才中止事件流
const stopStream = Rx.Observable.fromEvent(document.querySelector('button','click'));
input.takeUntil(stopStream)
    .map(event => event.target.value)
    .subscribe(value => console.log(value));// hello ,點擊才能看到

處理產生的值

仍是以上個代碼爲例:輸入 「hello world"

const input = Rx.Observable.fromEvent(document.querySelector('input'),'input');
// 傳遞一個值,不作處理
input.map(event => event.target.value)
    .subscribe(value => console.log(value));// 'h'

// 經過提取屬性產生一個新的值
input.pluck('target','value')
    .subscribe(value => console.log(value));// 'h'
// 傳遞以前的兩個值
input.pluck('target','value').pairwise()
    .subscribe(value => console.log(value));// ['h','he']

// 只會經過惟一的值
input.pluck('data').distinct()
    .subscribe(value => console.log(value));// 'helo wrd'

// 不會傳遞與上一個重複的值
input.pluck('data').distinctUntilChanged()
    .subscribe(value => console.log(value)); // 'helo world'

因此,綜上可得,一個 observable 在程序中通過了產生 --> 控制流動方式 --> 最後產生的值的處理 --> 訂閱 的四大過程。

相關文章
相關標籤/搜索