摘要:響應(yīng)式組件上節(jié)中錯(cuò)誤的把添加到了中,實(shí)際中它返回的是一個(gè),先調(diào)整過(guò)來(lái)。將這兩條流合并成一條請(qǐng)求流。利用上面實(shí)現(xiàn)的方法,可以很方便的拿到響應(yīng)流,即。由于不同于,請(qǐng)求和響應(yīng)一一對(duì)應(yīng)的很好,所以這里可能需要一定的條件來(lái)拿到請(qǐng)求對(duì)應(yīng)的響應(yīng)。
上回搭建了一個(gè)組件以及它所依賴的服務(wù)的基本結(jié)構(gòu),這節(jié)接著它繼續(xù)。另外從本節(jié)開(kāi)始,統(tǒng)一采用rxjs6的風(fēng)格,6和5在寫(xiě)法上最大的不同就是棄用鏈?zhǔn)秸{(diào)用,而采用pipe的方法,當(dāng)然也有一些其它的變更,請(qǐng)自行翻閱文檔。
響應(yīng)式組件上節(jié)中錯(cuò)誤的把generateRandomCode 添加到了 subscription中,實(shí)際中它返回的是一個(gè)Observable,先調(diào)整過(guò)來(lái)。
initialModel() { this.randomCode = this.auth.generateRandomCode(this.generateCode$); }
刪除 launch方法中的 .add(this.auth.generateRandomCode(this.generateCode$));
服務(wù)代碼驗(yàn)證碼變更的邏輯有兩處,第一是程序設(shè)定好的時(shí)間周期到達(dá)后,第二是用戶點(diǎn)點(diǎn)擊時(shí)。我們的組件中已經(jīng)設(shè)置了一個(gè)subject來(lái)獲取用戶的輸入,并且已經(jīng)傳給了服務(wù),現(xiàn)在我們來(lái)完善服務(wù)中獲取驗(yàn)證碼的邏輯,也就是那個(gè)generateRandomCode方法。
generateRandomCode(signal: Observable): Observable { // 每30秒向后臺(tái)獲取一次驗(yàn)證碼 const period = timer(0, 1000 * 30) // 第一個(gè)參數(shù)延遲時(shí)間,第二個(gè)參數(shù)間隔周期。 .pipe( mapTo(true) ); // 將這兩條流合并成一條請(qǐng)求流。 const request = merge(signal, period); // 修改返回,當(dāng)請(qǐng)求流中產(chǎn)生數(shù)據(jù)后,向服務(wù)器請(qǐng)求并將結(jié)果返回。 return request.pipe( switchMapTo(this.http.get(url)), map((res: Response)) => { // 假設(shè)數(shù)據(jù)保存在random 字段下 const body = res.json(); return body.data.random; } ) }
隨便碼請(qǐng)求的過(guò)程就完成了,當(dāng)然還可以添加其它邏輯,如限制用戶10秒內(nèi)最多可以獲取一次,可以給傳入的 signal 加 debounce time
const signal2 = signal.pipe( debounceTime(10 * 1000) )
另外還有對(duì)于錯(cuò)誤的處理等,可以參照之前 前端大耍 的那篇 《Angular Http 請(qǐng)求出錯(cuò)后重試》。
既然說(shuō)到了http的失敗重試,其實(shí)websocket也一樣。
websocket的響應(yīng)式首先我們實(shí)現(xiàn)一個(gè)建議websocket連接的方法,代碼如下:
// url 和 protocols 不需要解釋; input: 請(qǐng)求數(shù)據(jù)的流,通過(guò)它來(lái)向服務(wù)端發(fā)送數(shù)據(jù)。 function connect(url, input, protocols) { const connectionStatus = new BehaviorSubject(0); // 用來(lái)查看當(dāng)前連接的狀態(tài)。 const messages = new Observable(function (observer) { const socket = new WebSocket(url, protocols); const inputSubscription; const open = false; const forcedClose = false; const closed = () => { if (!open) return; connectionStatus.next(connectionStatus.getValue() - 1); open = false; }; socket.onopen = () => { open = true; connectionStatus.next(connectionStatus.getValue() + 1); inputSubscription = input.subscribe( data => socket.send(data)); }; socket.onmessage = message => observer.next(message.data); socket.onerror = error => { closed(); observer.error(error); }; socket.onclose = event => { closed(); if (forcedClose) observer.complete(); else observer.error(new Error(event.reason)); }; return function () { forcedClose = true; if (inputSubscription) inputSubscription.unsubscribe(); if (open) { closed(); socket.close(); } }; }); return { messages: messages, connectionStatus: connectionStatus }; }
利用上面實(shí)現(xiàn)的方法,可以很方便的拿到響應(yīng)流,即 message。
@Injectable() export class WebSocketService { inputStream: Subject= new Subject(); // 和上面寫(xiě)好的方法進(jìn)行通信 message: Observable ; // 暴露給調(diào)用者來(lái)獲取數(shù)據(jù) constructor() { this.connect() } // 暴露給其它服務(wù)或組件來(lái)發(fā)送數(shù)據(jù),同時(shí)獲得請(qǐng)求對(duì)應(yīng)的響應(yīng)。 send(data) { this.inputStream.next(data); // 由于websocket 不同于http,請(qǐng)求和響應(yīng)一一對(duì)應(yīng)的很好,所以這里可能需要一定的條件來(lái)拿到請(qǐng)求對(duì)應(yīng)的響應(yīng)。 return this.message.pipe( filter(message => message.flag === data.flag) ); } private connect(): void { if(this.message) return; const { message, connectStatus } = connect(youUrl, this.inputSteam); this.message = message.pipe( map(response => /*處理數(shù)據(jù)邏輯*/), retryWhen(error => error.pipe( tap(err => console.log(err)), // 打印一下錯(cuò)誤,可以換成其它的邏輯。 delay(500) // 500毫秒后發(fā)起重試 )), share() // 將這個(gè)流變?yōu)閔ot,至于流的hot 和 cold可能需要多帶帶的文章來(lái)解釋。 ); connectStatus.subscribe(status => console.log("當(dāng)前連接的狀態(tài):" + status)) } }
可以看出在響應(yīng)式的代碼中,很少需要維護(hù)一些中間數(shù)據(jù)狀態(tài),數(shù)據(jù)都是在流中獲取,轉(zhuǎn)換和傳遞,訂閱者對(duì)數(shù)據(jù)最好可以實(shí)現(xiàn)開(kāi)箱即用,無(wú)需另外的加工。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97259.html
摘要:使用則需要及以上版本。開(kāi)發(fā)使用框架七系列教程目錄系列教程大綱快速入門(mén)實(shí)踐實(shí)踐整合整合中和實(shí)踐整合中實(shí)現(xiàn)緩存中實(shí)現(xiàn)通信集成測(cè)試及部署實(shí)戰(zhàn)圖書(shū)管理系統(tǒng) WebFlux 系列教程大綱 一、背景 大家都知道,Spring Framework 是 Java/Spring 應(yīng)用程序跨平臺(tái)開(kāi)發(fā)框架,也是 Java EE(Java Enterprise Edition) 輕量級(jí)框架,其 Spring ...
摘要:所以一個(gè)網(wǎng),甚至是響應(yīng)式設(shè)計(jì),在兩個(gè)平臺(tái)上都會(huì)損害您整體的。三響應(yīng)式與如果把網(wǎng)站作為一個(gè)單獨(dú)的網(wǎng)站,如果網(wǎng)站的內(nèi)容與桌面版的內(nèi)容相對(duì)缺少,導(dǎo)致用戶回到桌面端的網(wǎng)站,會(huì)記錄這種選擇,使搜索排名降低,國(guó)內(nèi)百度就不知道會(huì)怎樣。 一、為什么需要響應(yīng)式設(shè)計(jì)(responsible web design) 1. 響應(yīng)式發(fā)展背景 1、屏幕尺寸的快速變化,iphone為320x480,分辨率在未來(lái)可以...
摘要:響應(yīng)式命令式這兩種編程風(fēng)格的思維方式是完全相反的。第二種方式是工人主動(dòng)去找工人索取生產(chǎn)手機(jī)所要的零件,然后生產(chǎn)一臺(tái)完整的手機(jī),這兩種方式就對(duì)應(yīng)的響應(yīng)式和命令式。 angular2中內(nèi)置了rxjs,雖然框架本身并沒(méi)有強(qiáng)制開(kāi)發(fā)者使用響應(yīng)式風(fēng)格來(lái)組織代碼,但是從框架開(kāi)發(fā)團(tuán)隊(duì)的角度可以看出他們必然是認(rèn)同這種編程風(fēng)格的。rxjs本質(zhì)是基于函數(shù)式編程的響應(yīng)式風(fēng)格的庫(kù),函數(shù)式相對(duì)于面向?qū)ο髞?lái)說(shuō)更加抽...
摘要:發(fā)布通過(guò)回調(diào)方法向發(fā)布事件。觀察者一個(gè)回調(diào)函數(shù)的集合,它知道如何去監(jiān)聽(tīng)由提供的值。 本文目錄 一、項(xiàng)目起步 二、編寫(xiě)路由組件 三、編寫(xiě)頁(yè)面組件 1.編寫(xiě)單一組件 2.模擬數(shù)據(jù) 3.編寫(xiě)主從組件 四、編寫(xiě)服務(wù) 1.為什么需要服務(wù) 2.編寫(xiě)服務(wù) 五、引入RxJS 1.關(guān)于RxJS 2.引入RxJS 3.改造數(shù)據(jù)獲取方式 六、改造組件 1.添...
閱讀 1486·2021-10-13 09:39
閱讀 1409·2021-09-23 11:22
閱讀 2311·2019-08-30 14:05
閱讀 1131·2019-08-29 17:03
閱讀 871·2019-08-29 16:24
閱讀 2294·2019-08-29 13:51
閱讀 720·2019-08-29 13:00
閱讀 1431·2019-08-29 11:24