使用RxJS更優(yōu)雅地進(jìn)行定時(shí)請(qǐng)求詳析
在用 Angular 做項(xiàng)目的時(shí)候,遇到了一個(gè)有點(diǎn)麻煩的問題。具體問題如下:
輪循請(qǐng)求某個(gè)接口,如何保證接口返回的數(shù)據(jù)與請(qǐng)求的順序相同?
實(shí)際的業(yè)務(wù)場景是這樣的:前端需要輪循請(qǐng)求后端接口獲取文件處理進(jìn)度,并在前端用進(jìn)度條展示。如下方所示:
首先想到的肯定是使用 setTimeout 或者 setInterval 進(jìn)行定時(shí)請(qǐng)求。然而結(jié)果有點(diǎn)詭異,進(jìn)度條的變化不是遞增,而是有快有慢,比如 30%,20%,50%,40%這樣。仔細(xì)一想也知道問題出在哪,異步請(qǐng)求的結(jié)果并不是按順序返回的。
我在之前的工作中還沒有遇到過這類需求,所以我并不是很清楚如果用傳統(tǒng)方式應(yīng)該如何解決。然而很慶幸的是 RxJS 正好擅長處理這樣的問題。我立即翻了一下文檔,interval 操作符可以處理定時(shí)任務(wù),而且更強(qiáng)大的是返回結(jié)果也是有順序的。
interval(period: 0 = 0, scheduler: SchedulerLike = async): Observable<number>
首先看一下 interval 的說明:
創(chuàng)建一個(gè)可觀察對(duì)象,在規(guī)定的調(diào)度程序中,以規(guī)定的時(shí)間間隔發(fā)出連續(xù)的數(shù)值。
interval 返回一個(gè)可觀察對(duì)象,它可以周期性的發(fā)出遞增數(shù)值,但是第一次發(fā)出值是在第一個(gè)周期結(jié)束之后執(zhí)行的。
以下是官方例子:
import { interval } from 'rxjs'; import { take } from 'rxjs/operators'; const numbers = interval(1000); const takeFourNumbers = numbers.pipe(take(4)); takeFourNumbers.subscribe(x => console.log('Next: ', x)); // Logs: // Next: 0 // Next: 1 // Next: 2 // Next: 3
不過只看官方例子還是有點(diǎn)懵,如果是 http 請(qǐng)求的話應(yīng)該怎么寫參數(shù)呢?或者說應(yīng)該把 http 請(qǐng)求寫在哪里?
這個(gè)地方的坑有點(diǎn)深,通過翻閱外文資料終于找到答案。直接上代碼。
// 間隔 1s 請(qǐng)求 this.timer$ = interval(1000) .pipe( // 取消過時(shí)的請(qǐng)求值 switchMap(() => { return this.http.get(API); }), ) .subscribe( (res: any) => { // 百分?jǐn)?shù)處理邏輯 }, () => { this.timer$.unsubscribe(); }, () => { this.timer$.unsubscribe(); }, );
總的來說就是通過管道處理請(qǐng)求。最終的效果很完美。
總結(jié)
RxJS 確實(shí)是一個(gè)非常強(qiáng)大的工具庫,尤其處理異步交互真的是省時(shí)省力,但是國內(nèi)技術(shù)文章偏少,遇到疑難問題還需要查閱國外文章。歡迎大家評(píng)論交流。
好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
AngularJS中的Directive實(shí)現(xiàn)延遲加載
延遲加載通常是直到用戶交互時(shí)才加載,那么如何實(shí)現(xiàn)延時(shí)加載的呢?下面通過本文一起學(xué)習(xí)AngularJS中的Directive實(shí)現(xiàn)延遲加載,對(duì)angularjs延時(shí)加載相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2016-01-01仿Angular Bootstrap TimePicker創(chuàng)建分鐘數(shù)-秒數(shù)的輸入控件
這篇文章主要為大家詳細(xì)介紹了仿Angular Bootstrap TimePicker創(chuàng)建分鐘數(shù)-秒數(shù)的輸入控件的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-07-07不能不知道的10個(gè)angularjs英文學(xué)習(xí)網(wǎng)站
這篇文章主要為大家分享了10個(gè)大家不能不知道的angularjs英文網(wǎng)站,供大家學(xué)習(xí),感興趣的小伙伴們可以參考一下2016-03-03AngularJs篇:使用AngularJs打造一個(gè)簡易權(quán)限系統(tǒng)的實(shí)現(xiàn)代碼
本篇文章主要介紹了AngularJs篇:使用AngularJs打造一個(gè)簡易權(quán)限系統(tǒng)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-12-12使用Angular CLI進(jìn)行單元測試和E2E測試的方法
這篇文章主要介紹了使用Angular CLI進(jìn)行單元測試和E2E測試的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03Angular6 用戶自定義標(biāo)簽開發(fā)的實(shí)現(xiàn)方法
這篇文章主要介紹了Angular6 用戶自定義標(biāo)簽開發(fā)的實(shí)現(xiàn)方法,下面我們就通過一個(gè)簡單的例子演示Angular6中的這一新功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,需要的朋友可以參考下2019-01-01AngularJS equal比較對(duì)象實(shí)例詳解
這篇文章主要介紹了AngularJS API之equal比較對(duì)象的相關(guān)資料,需要的朋友可以參考下2016-09-09Angualrjs 表單驗(yàn)證的兩種方式(失去焦點(diǎn)驗(yàn)證和點(diǎn)擊提交驗(yàn)證)
AngularJS提供了表單驗(yàn)證,但是驗(yàn)證的過程交互體驗(yàn)很不好,比如重設(shè)密碼,重復(fù)密碼的時(shí)候一鍵入就會(huì)提示密碼不正確?,F(xiàn)在小編給大家整理了兩種方法,需要的的朋友參考下吧2017-05-05angular動(dòng)態(tài)刪除ng-repaeat添加的dom節(jié)點(diǎn)的方法
本篇文章主要介紹了angular動(dòng)態(tài)刪除ng-repaeat添加的dom節(jié)點(diǎn)的方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-07-07