rxjs隨筆1--rxjs能作什麼

首先咱們要弄懂這幾個問題:
1.rxjs是什麼
2.rxjs能作什麼
3.已經有了promise的狀況下爲何還須要rxjs
4.rxjs的使用方法
若是這些問題都直接去網上搜而後貼上連接,感受我這篇文章就沒什麼寫的必要了。固然了資料已經很是多了,確實不須要我再爲你們寫一點所謂有幫助的文章了。那麼爲何還要寫呢,寫這個是爲了本身,爲了本身可以更好的理解rxjs,與你們無關,也與白潔無關。javascript

1.rxjs是什麼

RxJS 是一個庫,它經過使用 observable 序列來編寫異步和基於事件的程序。它提供了一個核心類型 Observable,附屬類型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 啓發的操做符 (map、filter、reduce、every, 等等),這些數組操做符能夠把異步事件做爲集合來處理。前端

2.rxjs能作什麼

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

3.已經有了promise的狀況下爲何還須要rxjs

Promise:promise已經解決了不少異步的難點,好比將回調地獄改成了鏈式調用,統一同步和異步代碼,可是promise只有一個結果,而且不能夠被提早取消(講真,多是我作的工做都太簡單了,這些問題其實我並無真正遇到過)ajax

4.rxjs的使用方法

異步 API
各類異步的API
DOM Events
XMLHttpRequest
fetch
WebSocket
Service Worker
setTimeout
setInterval
requestAnimationFrame
若是使用rxjs來處理,可使用統一的API,並且藉助rxjs各類強大的操做符,能夠很是簡單的實現需求。對於不一樣的場景使用不一樣API來完成功能:後端

  1. 建立 Observable 的方法、types、schedulers 和一些工具方法
import { Observable, Subject, asapScheduler, pipe, of, from, interval, merge, fromEvent, SubscriptionLike, PartialObserver } from 'rxjs';
// asapScheduler SubscriptionLike PartialObserver 沒有使用過
  1. 操做符(能夠理解爲rxjs提供的一些快捷功能,對Observe中的produce產生的數據的預處理,處理完成以後再到subscribe中的觀察者中進行處理)
import { map, filter, scan, take, takeUtil } from 'rxjs/operators';
  1. webSocket
import { webSocket } from 'rxjs/webSocket';

4.ajax

import { ajax } from 'rxjs/ajax';

建立Observable

建立Observable主要有兩步數組

  1. new Observable時接受一個產生數據的方法function,function產生數據的方式爲function接受一個形參(ob)ob有三個屬性:next,error,complete。在方法內使用ob.next('但願傳出的值'),來向外面傳輸流。
  2. new Observable後返回一個對象,這個對象通常使用$做爲後綴便於標識,在這個對象上調用subscribe方法傳入你所但願的觀察者函數。
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')
  1. 對數據流的預處理,這是兩步以外的,但仍是但願一塊兒講。對數據的預處理,new Observable產生的發出數據流對象以前,能夠調用pipe方法來對數據進行預處理叫作Operators操做符。注意⚠️,每個操做符都會返回一個全新的Observable對象
source$.pipe(
    take(5), // 只要前五個
    first(), // 是得到知足判斷條件的第一個數據
)

要實現的功能

  1. 實現相似promise的功能,單個的Promise.then()

可使用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()
相關文章
相關標籤/搜索