首先咱們要弄懂這幾個問題:
1.rxjs是什麼
2.rxjs能作什麼
3.已經有了promise的狀況下爲何還須要rxjs
4.rxjs的使用方法
若是這些問題都直接去網上搜而後貼上連接,感受我這篇文章就沒什麼寫的必要了。固然了資料已經很是多了,確實不須要我再爲你們寫一點所謂有幫助的文章了。那麼爲何還要寫呢,寫這個是爲了本身,爲了本身可以更好的理解rxjs,與你們無關,也與白潔無關。javascript
RxJS 是一個庫,它經過使用 observable 序列來編寫異步和基於事件的程序。它提供了一個核心類型 Observable,附屬類型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 啓發的操做符 (map、filter、reduce、every, 等等),這些數組操做符能夠把異步事件做爲集合來處理。前端
javascript寫前端頁面的時候,除了展現數據UI以外,還須要相應用戶的操做,展現動態的數據,展現動態的UI。因而前端的異步有:事件(event)、ajax、動畫(animation)、定時器(timer)。 處理這些的時候常見的問題有:異步的回調地獄(callback hell) 競態條件(race condition) 內存泄漏(memory leak) 管理複雜狀態(manage complex states) 錯誤處理(exception handling)java
1.回調地獄:按照普通的javascript方法寫,全部的處理寫在某個事件的完成後的回調中,當有多個回調依次執行後1->2->3->4很容易將代碼寫成火箭形,很大一團根本沒發改。
2.競態條件:是指系統出現不恰當的執行時序,而獲得不正確的結果。好比搜索框中,每次輸入後發送請求獲取結果展現在搜索框下面,因爲網絡或者後端查詢的緣由有可能致使最後發送的請求比以前的請求更快的完成了,這時最終展示的並非最後那個請求的結果,而這並非咱們所但願的。
3.內存泄漏:當單頁面應用切換頁面時未在合適的時機移除監聽事件形成內存泄漏
4.複雜狀態的管理:異步帶來了狀態的改變,可能會使狀態管理變得很是複雜,尤爲是某個狀態有多個來源時,好比有些應用,一開始有一個默認值,再經過 AJAX 獲取初始狀態,存儲在 localStorage,以後經過 WebSocket 獲取更新。這時查詢狀態多是同步或者異步的,狀態的變動多是主動獲取也多是被動推送的,若是還有各類排序、篩選,狀態管理將會更加複雜。
5.錯誤處理:javascript中的try catch只能捕獲同步的錯誤,對於異步的錯誤難以獲取。promise中可使用一個全局的catch。web
Promise:promise已經解決了不少異步的難點,好比將回調地獄改成了鏈式調用,統一同步和異步代碼,可是promise只有一個結果,而且不能夠被提早取消(講真,多是我作的工做都太簡單了,這些問題其實我並無真正遇到過)ajax
異步 API
各類異步的API
DOM Events
XMLHttpRequest
fetch
WebSocket
Service Worker
setTimeout
setInterval
requestAnimationFrame
若是使用rxjs來處理,可使用統一的API,並且藉助rxjs各類強大的操做符,能夠很是簡單的實現需求。對於不一樣的場景使用不一樣API來完成功能:後端
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, SubscriptionLike, PartialObserver } from 'rxjs'; // asapScheduler SubscriptionLike PartialObserver 沒有使用過
import { map, filter, scan, take, takeUtil } from 'rxjs/operators';
import { webSocket } from 'rxjs/webSocket';
import { ajax } from 'rxjs/ajax';
建立Observable主要有兩步數組
import { Observable } from 'rxjs'; const source$ = new Observable(observer => { let number = 1 setInterval(() => { observer.next(number++) }, 1000) }) const observer = { next : item => console.log(item) } console.log('start') source$.subscribe(observer) console.log('end')
source$.pipe( take(5), // 只要前五個 first(), // 是得到知足判斷條件的第一個數據 )
可使用concatMap操做符promise
new Observable((observe) => { setTimeout(() => observe.next(['first']), 1000) }).pipe( concatMap(value => { console.log(value); return new Observable((observe) => { setTimeout(() => observe.next(value.concat('two')), 1000) }) }), ).subscribe()
2.網絡
實現相似promise的鏈式調用
使用concatMap,具體寫法相似異步
from(this.getUserInfo()) .pipe( concatMap(userInfo => this.getUserParent(userInfo)), concatMap(parentInfo => this.get(...)) )
3.實現相似promise.all的效果
forkJoin()