使用RxJS更优雅地进行定时请求详析


Posted in Javascript onJune 02, 2019

在用 Angular 做项目的时候,遇到了一个有点麻烦的问题。具体问题如下:

轮循请求某个接口,如何保证接口返回的数据与请求的顺序相同?

实际的业务场景是这样的:前端需要轮循请求后端接口获取文件处理进度,并在前端用进度条展示。如下方所示:

使用RxJS更优雅地进行定时请求详析

首先想到的肯定是使用 setTimeout 或者 setInterval 进行定时请求。然而结果有点诡异,进度条的变化不是递增,而是有快有慢,比如 30%,20%,50%,40%这样。仔细一想也知道问题出在哪,异步请求的结果并不是按顺序返回的。

我在之前的工作中还没有遇到过这类需求,所以我并不是很清楚如果用传统方式应该如何解决。然而很庆幸的是 RxJS 正好擅长处理这样的问题。我立即翻了一下文档,interval 操作符可以处理定时任务,而且更强大的是返回结果也是有顺序的。

interval(period: 0 = 0, scheduler: SchedulerLike = async): Observable<number>

首先看一下 interval 的说明:

创建一个可观察对象,在规定的调度程序中,以规定的时间间隔发出连续的数值。

使用RxJS更优雅地进行定时请求详析

interval 返回一个可观察对象,它可以周期性的发出递增数值,但是第一次发出值是在第一个周期结束之后执行的。

以下是官方例子:

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

不过只看官方例子还是有点懵,如果是 http 请求的话应该怎么写参数呢?或者说应该把 http 请求写在哪里?

这个地方的坑有点深,通过翻阅外文资料终于找到答案。直接上代码。

// 间隔 1s 请求
this.timer$ = interval(1000)
  .pipe(
    // 取消过时的请求值
    switchMap(() => {
      return this.http.get(API);
    }),
  )
  .subscribe(
    (res: any) => {
      // 百分数处理逻辑
    },
    () => {
      this.timer$.unsubscribe();
    },
    () => {
      this.timer$.unsubscribe();
    },
  );

总的来说就是通过管道处理请求。最终的效果很完美。

总结

RxJS 确实是一个非常强大的工具库,尤其处理异步交互真的是省时省力,但是国内技术文章偏少,遇到疑难问题还需要查阅国外文章。欢迎大家评论交流。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
使用JavaScript构建JSON格式字符串实现步骤
Mar 22 Javascript
javaScript中slice函数用法实例分析
Jun 08 Javascript
深入理解JavaScript中的对象复制(Object Clone)
May 18 Javascript
微信小程序 教程之模块化
Oct 17 Javascript
jQuery Password Validation密码验证
Dec 30 Javascript
JS使用插件cryptojs进行加密解密数据实例
May 11 Javascript
angularJs中datatable实现代码
Jun 03 Javascript
vue项目中使用百度地图的方法
Jun 08 Javascript
微信小程序简单的canvas裁剪图片功能详解
Jul 12 Javascript
JavaScript面向对象程序设计中对象的定义和继承详解
Jul 29 Javascript
使用 JavaScript 创建并下载文件(模拟点击)
Oct 25 Javascript
vue @ ~ 相对路径 路径别名设置方式
Jun 05 Vue.js
Vue CLI3基础学习之pages构建多页应用
Jun 02 #Javascript
Vue基础学习之项目整合及优化
Jun 02 #Javascript
JavaScript判断对象和数组的两种方法
May 31 #Javascript
vue中node_modules中第三方模块的修改使用详解
May 31 #Javascript
Vuex新手的理解与使用详解
May 31 #Javascript
一文快速了解JQuery中的AJAX
May 31 #jQuery
gulp构建小程序的方法步骤
May 31 #Javascript
You might like
PHP exif扩展方法开启详解
2014/07/28 PHP
PHP中array_slice函数用法实例详解
2014/11/25 PHP
PHP实现通过CURL上传文件功能示例
2018/05/30 PHP
php中array_fill函数的实例用法
2021/03/02 PHP
javascript 密码强度验证规则、打分、验证(给出前端代码,后端代码可根据强度规则翻译)
2010/05/18 Javascript
没有document.getElementByName方法
2013/08/19 Javascript
一个非常全面的javascript URL解析函数和分段URL解析方法
2014/04/12 Javascript
seajs加载jquery时提示$ is not a function该怎么解决
2015/10/23 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
2016/01/27 Javascript
Mac下使用charles遇到的问题以及解决办法
2017/01/10 Javascript
Angular.js跨controller实现参数传递的两种方法
2017/02/20 Javascript
详细讲解vue2+vuex+axios
2017/05/27 Javascript
vue-cli开发时,关于ajax跨域的解决方法(推荐)
2018/02/03 Javascript
React性能优化系列之减少props改变的实现方法
2019/01/17 Javascript
Vue动态面包屑功能的实现方法
2019/07/01 Javascript
es6中Promise 对象基本功能与用法实例分析
2020/02/23 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
[02:47]DOTA2英雄基础教程 野性怒吼兽王
2013/12/05 DOTA
Python学习笔记之Break和Continue用法分析
2019/08/14 Python
Python 自动登录淘宝并保存登录信息的方法
2019/09/04 Python
python实现按首字母分类查找功能
2019/10/31 Python
Python读取文件内容为字符串的方法(多种方法详解)
2020/03/04 Python
django执行原始查询sql,并返回Dict字典例子
2020/04/01 Python
python爬虫学习笔记之Beautifulsoup模块用法详解
2020/04/09 Python
python计算auc的方法
2020/09/09 Python
iframe在移动端的缩放的示例代码
2018/10/12 HTML / CSS
欧洲、亚洲、非洲和拉丁美洲的度假套餐:Great Value Vacations
2019/03/30 全球购物
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
土木工程专业自荐信
2013/10/04 职场文书
大学生自我鉴定评语
2014/01/27 职场文书
优秀部门获奖感言
2014/02/14 职场文书
应届毕业生自荐信例文
2014/02/26 职场文书
城管执法人员纪律作风整顿思想汇报
2014/09/13 职场文书
社区工作者个人总结
2015/02/28 职场文书
Vue Element UI自定义描述列表组件
2021/05/18 Vue.js
科普 | 业余无线电知识-波段篇
2022/02/18 无线电