使用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 相关文章推荐
一个收集图片的bookmarlet(js 刷新页面中的图片)
May 27 Javascript
javascript:json数据的页面绑定示例代码
Jan 26 Javascript
js获得参数的getParameter使用示例
Feb 26 Javascript
常用的JS验证和函数汇总
Dec 23 Javascript
使用jquery+CSS实现控制打印样式
Dec 31 Javascript
JQuery悬停控制图片轮播——代码简单
Aug 05 Javascript
javascript封装addLoadEvent实现页面同时加载执行多个函数的方法
Jul 25 Javascript
浅谈Javascript数据属性与访问器属性
Jul 26 Javascript
JavaScript编码风格指南(中文版)
Aug 26 Javascript
如何获取TypeScript的声明文件.d.ts
May 01 Javascript
Angular搜索场景中使用rxjs的操作符处理思路
May 30 Javascript
JS回调函数深入理解
Oct 16 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 透明水印生成代码
2012/08/27 PHP
Javascript miscellanea -display data real time, using window.status
2007/01/09 Javascript
为指定元素增加样式的js代码
2009/12/09 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
5个javascript的数字格式化函数分享
2011/12/07 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
js动态创建标签示例代码
2014/06/09 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
JavaScript使用Math.Min返回两个数中较小数的方法
2015/04/06 Javascript
详解js中Number()、parseInt()和parseFloat()的区别
2016/12/20 Javascript
原生JavaScript实现AJAX、JSONP
2017/02/07 Javascript
Angular directive递归实现目录树结构代码实例
2017/05/05 Javascript
JavaScript调试之console.log调试的一个小技巧分享
2017/08/07 Javascript
详解JS数组Reduce()方法详解及高级技巧
2017/08/18 Javascript
jQuery实现的点击标题文字切换字体效果示例【测试可用】
2018/04/26 jQuery
vue.js 中使用(...)运算符报错的解决方法
2018/08/09 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
2019/03/15 Javascript
微信小程序实现消息框弹出动画
2020/04/18 Javascript
Vue实现商品飞入购物车效果(电商项目)
2019/11/26 Javascript
Vue中fragment.js使用方法小结
2020/02/17 Javascript
基于better-scroll 实现歌词联动功能的代码
2020/05/07 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
Python合并字典键值并去除重复元素的实例
2016/12/18 Python
python strip() 函数和 split() 函数的详解及实例
2017/02/03 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
Python使用tkinter模块实现推箱子游戏
2019/10/08 Python
Python Opencv实现单目标检测的示例代码
2020/09/08 Python
学生如何注册Pycharm专业版以及pycharm的安装
2020/09/24 Python
Python __slots__的使用方法
2020/11/15 Python
python中pyqtgraph知识点总结
2021/01/26 Python
python绘图模块之利用turtle画图
2021/02/12 Python
Marks & Spencer爱尔兰:英国马莎百货
2016/04/20 全球购物
捐书寄语赠言
2014/01/18 职场文书
祖国在我心中演讲稿450字
2014/09/05 职场文书
python xlwt模块的使用解析
2021/04/13 Python
MySQL数据迁移相关总结
2021/04/29 MySQL