使用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 相关文章推荐
document对象execCommand的command参数介绍
Aug 01 Javascript
showModalDialog在谷歌浏览器下会返回Null的解决方法
Nov 27 Javascript
javascript匿名函数应用示例介绍
Mar 07 Javascript
Jquery Mobile 自定义按钮图标
Nov 18 Javascript
Uploadify上传文件方法
Mar 16 Javascript
JS获得多个同name 的input输入框的值的实现方法
Jan 09 Javascript
react-native-fs实现文件下载、文本存储的示例代码
Sep 22 Javascript
解决在vue项目中webpack打包后字体不生效的问题
Sep 01 Javascript
在vue项目中使用md5加密的方法
Sep 14 Javascript
详解Vue中watch对象内属性的方法
Feb 01 Javascript
layui固定下拉框的显示条数(有滚动条)的方法
Sep 10 Javascript
vue实现公共方法抽离
Jul 31 Javascript
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几个数学计算的内部函数学习整理
2011/08/06 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
100多行PHP代码实现socks5代理服务器[2]
2016/05/05 PHP
实现PHP搜索加分页
2016/10/12 PHP
PHP调试及性能分析工具Xdebug详解
2017/02/09 PHP
ThinkPHP5框架缓存查询操作分析
2018/05/30 PHP
php中isset与empty函数的困惑与用法分析
2019/07/05 PHP
php输出反斜杠的实例方法
2019/09/19 PHP
php中加密解密DES类的简单使用方法示例
2020/03/26 PHP
ExtJs事件机制基本代码模型和流程解析
2010/10/24 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
jQuery创建DOM元素实例解析
2015/01/19 Javascript
jQuery鼠标事件汇总
2015/08/30 Javascript
封装好的javascript前端分页插件pagination
2016/01/04 Javascript
AngularJS用户选择器指令实例分析
2016/11/04 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
nodeJs链接Mysql做增删改查的简单操作
2017/02/04 NodeJs
简单实现jQuery弹窗效果
2017/10/30 jQuery
原生JS实现的雪花飘落动画效果
2018/05/03 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
使用axios请求时,发送formData请求的示例
2019/10/29 Javascript
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
[46:04]Liquid vs VP Supermajor决赛 BO 第四场 6.10
2018/07/05 DOTA
如何使用python爬取csdn博客访问量
2016/02/14 Python
Python实现字典按照value进行排序的方法分析
2017/12/23 Python
python爬虫爬取快手视频多线程下载功能
2018/02/28 Python
Django使用中间件解决前后端同源策略问题
2019/09/02 Python
python os.rename实例用法详解
2020/12/06 Python
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
手工制作的意大利太阳镜和光学元件:Illesteva
2019/01/19 全球购物
预备党员思想汇报
2014/01/08 职场文书
体育专业自荐书
2014/05/29 职场文书
2015年采购员工作总结
2015/04/27 职场文书
寒假生活随笔
2015/08/15 职场文书
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript