一、Observable的性質
三種狀態:nex, error, complete
進入到Error狀態:
const interval$ = Rx.Observable.interval(1000) .filter(val=>{ throw '出錯了' }) .take(4) .reduce((x,y)=>{//reduce接收函式作為引數 return [...x,y]; },[]) interval$.subscribe( val=>console.log(val), err=>console.error('Error:' + err), ()=>console.log('I am complete') );
二、特殊型別的Observable
- 永不結束
- Never
- Empty
- Throw
永不結束:沒有complete狀態,比如計時器,每隔1s發射item。
Never:完全不發射item,也不結束。【測試時幫助構成條件】
const interval$ = Rx.Observable.never(); //不會emit任何元素,也不會結束 interval$.subscribe( val=>console.log(val), err=>console.error('Error:' + err), ()=>console.log('I am complete') );
Empty:流裡沒有元素,直接進入Complete狀態。
const interval$ = Rx.Observable.empty(); //不會輸出任何元素,直接結束 interval$.subscribe( val=>console.log(val), err=>console.error('Error:' + err), ()=>console.log('I am complete') );
Throw:不發生任何東西,直接進入Error狀態。
const interval$ = Rx.Observable.throw('出錯了'); interval$.subscribe( val=>console.log(val), err=>console.error('Error:' + err), ()=>console.log('I am complete') );
三、工具類操作符do
一般用來做除錯。
或者外部條件的設定。
流進入到下一步之前需要對外部的東西進行改變【寫檔案之類】
const interval$ = Rx.Observable.interval(1000) .map(val=>val*2) .do(v=>console.log('val is' +v)) //在map之後,take之前,在流發生之前看一下流裡有什麼東西 .take(3); interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
do很像臨時subscribe,但是沒有把流中斷掉。可以繼續應用操作符。臨時中間橋樑,列印值做除錯。
let logLabel='當前值是'; const interval$ = Rx.Observable.interval(1000) .map(val=>val*2) .do(v=>{ console.log(logLabel +v); //取得了外部的值 logLabel='當前'; //改變了外部的值 }) .take(4); interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
四、變換類操作符:scan
scan:
場景:記住之前的運算結果。每次運算都會發射值。
scan接收函式作為引數,x是增加器,預設初始值0,把函式返回的結果作為下次的x。
const interval$ = Rx.Observable.interval(1000) .filter(val=>val%2===0) .scan((x,y)=>{//scan接收函式作為引數 return x+y; }) .take(4) interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
五、數學類操作符reduce
陣列中也有,使用比較頻繁。
和scan對比,reduce只會發射一個最終值。
.filter(val=>val%2===0) .take(4) .reduce((x,y)=>{//reduce接收函式作為引數,只會發射一個最後的值 return x+y; }) interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
高階用法:
const interval$ = Rx.Observable.interval(1000) .filter(val=>val%2===0) .take(4) .reduce((x,y)=>{//reduce接收函式作為引數 return [...x,y]; //每次陣列加y },[]) //x初始值為空陣列[] interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
六、過濾類操作符 filter,take,first/last,skip...
filter:
let logLabel='當前值是'; const interval$ = Rx.Observable.interval(1000) .filter(val=>val%2===0) //過濾偶數 .do(v=>{console.log(logLabel +v); logLabel='當前';} ) .take(3); interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
first:
const interval$ = Rx.Observable.interval(1000) .filter(val=>val%2===0) .first() //和take(1)是一樣的,取第一個 // .take(1) interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
skip: 和take相反
const interval$ = Rx.Observable.interval(1000) .filter(val=>val%2===0) .skip(2); //過濾掉0和2 interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
七、常見建立類操作符:Interval,Timer
1、interval
const interval$ = Rx.Observable.interval(1000); interval$.subscribe(val=>console.log(val));
通過take取前3個來看三種狀態的效果
const interval$ = Rx.Observable.interval(1000).take(3); interval$.subscribe( val=>console.log(val), err=>console.log(err), ()=>console.log('I am complete') );
2、Timer
const timer$= Rx.Observable.timer(1000); timer$.subscribe(v=>console.log(v)); //控制檯只輸出一個值0
第一個引數:delay多長時間
第二個引數:之後要以什麼頻率傳送
const timer$= Rx.Observable.timer(1000,1000); timer$.subscribe(v=>console.log(v)); //類似interval,但是interval不能指定開始延遲時間
實踐:給Observable增加一個debug操作符
只有在生產環境才輸出
import {Observable} from 'rxjs/Observable'; import {environment} from '../../environments/environment'; declare module 'rxjs/Observable' { interface Observable<T> { debug: (...any) => Observable<T>; } } Observable.prototype.debug = function(message: string) { return this.do( (next) => { if (!environment.production) { console.log(message, next); } }, (err) => { if (!environment.production) { console.error('ERROR>>>', message, err); } }, () => { if (!environment.production) { console.log('Completed - '); } } ); };
本文作者starof,因知識本身在變化,作者也在不斷學習成長,文章內容也不定時更新,為避免誤導讀者,方便追根溯源,請諸位轉載註明出處:https://www.cnblogs.com/starof/p/9137865.html 有問題歡迎與我討論,共同進步。