<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
最近在專案當中別的小夥伴使用到了Rxjs
,我一眼看上去有點懵,感覺挺複雜,挺繞的。於是抓緊補補課,然後就可以和小夥伴們一起交流怎麼能優雅的使用Rxjs
。由於內容比較多,會分為三篇來講解說明
Observable
和 Observer
Operators
Subject
和Schedulers
RxJS是一個庫,可以使用可觀察佇列來編寫非同步和基於事件的程式的庫。
RxJS 中管理和解決非同步事件的幾個關鍵點:
map
、filter
、concat
、reduce
等操作的集合。setTimeout
or requestAnimationFrame
或者其它上時進行協調。我們通過在dom上繫結事件的小案例,感受一下Rxjs的魅力。
document.addEventListener('click', () => console.log('Clicked!'));
用Rxjs建立一個observable
,內容如下
import { fromEvent } from 'rxjs'; fromEvent(document, 'click').subscribe(() => console.log('Clicked!'));
let count = 0; document.addEventListener('click', () => console.log(`Clicked ${++count} times`));
用Rxjs可以隔離狀態,
import { fromEvent, scan } from 'rxjs'; fromEvent(document, 'click') .pipe(scan((count) => count + 1, 0)) .subscribe((count) => console.log(`Clicked ${count} times`));
可以看到,我們用到了scan
操作符,該操作符的工作方式和陣列的reduce
類似,回撥函數接收一個值, 回撥的返回值作為下一次回撥執行暴露的一個值。
通過上面的案例可以看出,RxJS
的強大之處在於它能夠使用純函數生成值。這意味著您的程式碼不太容易出錯。 通常你會建立一個不純的函數,你的程式碼的其他部分可能會弄亂你的狀態。
let count = 0; let rate = 1000; let lastClick = Date.now() - rate; document.addEventListener('click', () => { if (Date.now() - lastClick >= rate) { console.log(`Clicked ${++count} times`); lastClick = Date.now(); } });
使用Rxjs
fromEvent(document, 'click') .pipe( throttleTime(1000), scan((count) => count + 1, 0) ) .subscribe((count) => console.log(`Clicked ${count} times`));
RxJS 有一系列的操作符,可以幫助你控制事件如何在你的 observables 中流動。
let count = 0; const rate = 1000; let lastClick = Date.now() - rate; document.addEventListener('click', (event) => { if (Date.now() - lastClick >= rate) { count += event.clientX; console.log(count); lastClick = Date.now(); } });
使用Rxjs
import { fromEvent, throttleTime, map, scan } from 'rxjs'; fromEvent(document, 'click') .pipe( throttleTime(1000), map((event) => event.clientX), scan((count, clientX) => count + clientX, 0) ) .subscribe((count) => console.log(count));
從上面看可以通過map
去轉換observables
的值。
我們先來寫一個案例程式碼,大家可以猜下它的執行順序
import { Observable } from 'rxjs'; const observable = new Observable(subscriber => { subscriber.next(1); subscriber.next(2); subscriber.next(3); setTimeout(() => { subscriber.next(4); subscriber.complete(); }, 1000); }); console.log('just before subscribe'); observable.subscribe({ next(x) { console.log('got value ' + x); }, error(err) { console.error('something wrong occurred: ' + err); }, complete() { console.log('done'); } }); console.log('just after subscribe');
可以稍微想一下,正確的輸出結果
just before subscribe
got value 1
got value 2
got value 3
just after subscribe
got value 4
done
怎麼樣,和大家想的結果一樣嗎,我們來一下分析一下。
Observable 有兩種方式建立,一種是通過new Observable()
,還有一種是通過Rx.Observable.create()
的方式去建立。
Observable 核心的關注點:
建立Observable
const observable = new Observable(function subscribe(subscriber) { const id = setInterval(() => { subscriber.next('hi') }, 1000); });
該程式碼是建立一個Observable
,然後每隔1s向訂閱者傳送訊息。我們看到上邊的回撥函數是subscribe
, 該函數是描述Observable
最重要的部分。
observable.subscribe(x => console.log(x));
observable中的subscribe
中引數是一個回撥x => console.log(x)
,官方叫它Observer
,其實Observer
有多種形式,後邊我們會說到,在這裡就簡單理解,Observer
可以去消費資料,比如,在react中,我們這可以更新狀態資料等。
subscriber.next(1); // Next 通知 subscriber.complete(); // 完成 通知 subscriber.error(err); // Error 通知
其實就是執行一個惰性計算,可同步可非同步,
Observable Execution 可以傳遞三種型別的值:
Next
:傳送數值、字串、物件等。Error
:傳送 JavaScript 錯誤或異常。complete
:不傳送值。Next
通知是最重要和最常見的型別:它們代表傳遞給訂閱者的實際資料。在 Observable 執行期間,Error
和complete
通知可能只發生一次,並且只能有其中之一。
function subscribe(subscriber) { const intervalId = setInterval(() => { subscriber.next('hi'); }, 1000); return function unsubscribe() { clearInterval(intervalId); }; } const observable = new Observable(subscribe) const unsubscribe = observable.subscribe({next: (x) => console.log(x)}); // Later: unsubscribe(); // 取消執行
我們有看程式碼,建立了一個每秒輸出一個hi
內容的Observable
,但在我們的使用場景中,會有取消改行為,這時候就需要返回一個unsubscribe
的方法,用於取消。
我們在上邊的場景中也提到了Observer
, 但什麼是Observer
呢,其實就是資料的消費者,先回顧一下上面的程式碼
observable.subscribe(x => console.log(x));
其實可以寫成
const observer = { next: x => console.log('Observer got a next value: ' + x), error: err => console.error('Observer got an error: ' + err), complete: () => console.log('Observer got a complete notification'), }; observable.subscribe(observer);
這樣應就比較清晰了,observer
只是具有三個回撥的物件,每一個用於Observable
可能傳遞不同型別的通知。注意,observer
物件中的型別可以不必要全都寫。
其實observer
有許多變種,我們看下它的TS宣告就比較清楚了。
可以直接傳遞一個observer
物件,或者只傳遞一個next
回撥函數,在或者傳多個可選的回撥函數型別。
RxJS
不建議大家盲目的去用,一定要有合適的場景,盲目的去用可能會造成專案的複雜度會大幅度的提升。
以上就是RxJS中的Observable和Observer範例詳解的詳細內容,更多關於RxJS Observable Observer的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45