什麼是Operators
Operators是用來操作處理Observable 的一個函式,對單個或多個Observable進行一定處理後返回新的Observable。
描述各種Operators的功能時我們用Marble diagrams來視覺化的表達,不瞭解這種方式的同學可以參考IT邦的Marble diagrams的詳細介紹。
map 和 filter
map,filter和陣列的map類似,傳入一個callback,引數的意義也一樣。
interval(1000).pipe(
map(t => t = t + 1),
filter(t => !!(t % 2)) // 篩選出來奇數
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
map(x => x + 1)
map: -----1-----2-----3-----4--...
filter(t => !!(t % 2))
filter: -----1-----------3--------...
複製程式碼
mapTo
mapTo可以把傳進來的值改成一個固定的值
interval(1000).pipe(
mapTo(2)
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
mapTo(2)
mapTo: -----2-----2-----2-----2--...
複製程式碼
take 和 first
take是取前幾個元素後結束observable,first就是取第一個元素後直接結束,和take(1)一樣
interval(1000).pipe(
take(3)
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
take(3)
take: -----0-----1-----2
複製程式碼
skip
skip和take相反,用於跳過前面的n個元素
interval(1000).pipe(
skip(2)
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
skip(2)
skip: -----------------2-----3--...
複製程式碼
takeLast 和 last
takeLast 就是選取後n個元素,last就是取最後一個元素,因為是最後的元素,在為結束前無法預知何時結束,所以takelast是在observable完成以後再同步送出
interval(1000).pipe(
take(3),
takeLast(2)
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
take(3)
take: -----0-----1-----2
takeLast(2)
take: -----------------(12)
複製程式碼
takeUntil
takeUntil的作用是在某件事情發生時observer送出complete,從而停止並關閉這個observable,takeUntil中必須傳入一個observable物件。
let click = fromEvent(document.body, 'click');
interval(1000).pipe(
takeUntil(click)
).subscribe(res => console.log(res))
//Marble diagrams
origin: -----0-----1-----2-----3--...
takeUntil(click) click
takeUntil: -----0-----1-----2--
複製程式碼
takeUntil在實際工作中有很多運用,例如在離開某模組或者頁面時,觸發元件內所有observable的takeUntil,關閉所有監聽,防止浪費記憶體,還有在某些行為監聽中,當使用者觸發了特點行為關閉監聽。
concatAll
concatAll的作用是當observable送出的元素也是observable時,將所有observable串聯起來。需要注意的一點,不論是同步還是非同步的observable,先發出來的元素必須執行完才會執行下一個。
let obs1 = interval(1000).take(5);
let obs2 = interval(500).take(2);
let obs3 = interval(2000).take(1);
of(obs1, obs2, obs3).pipe(
concatAll()
).subscribe(res => cosnole(res))
origin : (o1 o2 o3)|
\ \ \
--0--1--2--3--4| -0-1| ----0|
concatAll()
concatAll: --0--1--2--3--4-0-1----0|
複製程式碼
concat
concat和concatAll一樣是把多個observable串聯起來,只是用法不一樣,concat可以傳入observable引數,可以用於在observable執行過程中插入新的observable。同樣,它要等到前一個observable完成後才能進行下一個的操作。
let obs2 = interval(500).take(2);
let obs3 = interval(500).take(1);
interval(1000).pipe(
take(3),
concat(obs2,obs3)
).subscribe(res => cosnole(res))
origin : ----0----1----2|
obs2: --0--1|
obs3: --0|
concat()
concat: ----0----1----2--0--1--0|
複製程式碼
小結
這些操作符都是比較簡單和常用的。下一篇會將其他操作符進行介紹。之後會有一個對操作符綜合使用的舉例。