使用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 变量命名规则
Sep 23 Javascript
jquery仿QQ商城带左右按钮控制焦点图片切换滚动效果
Jun 27 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
Mar 03 Javascript
Seajs 简易文档 提供简单、极致的模块化开发体验
Apr 13 Javascript
WEB 前端开发中防治重复提交的实现方法
Oct 26 Javascript
将angular.js项目整合到.net mvc中的方法详解
Jun 29 Javascript
AngularJS实现表单验证功能详解
Oct 12 Javascript
iview实现select tree树形下拉框的示例代码
Dec 21 Javascript
layui radio单选限制下一个radio单选的实例
Sep 03 Javascript
详解小程序如何改变onLoad的执行时机
Nov 01 Javascript
Vue路由对象属性 .meta $route.matched详解
Nov 04 Javascript
vue+echarts实现多条折线图
Mar 21 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 常用字符串函数总结
2008/03/15 PHP
php 自写函数代码 获取关键字 去超链接
2010/02/08 PHP
PHP清除数组中所有字符串两端空格的方法
2014/10/20 PHP
解决jquery的datepicker的本地化以及Today问题
2012/05/23 Javascript
JS定时关闭窗口的实例
2013/05/22 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
2014/05/16 Javascript
JavaScript实现信用卡校验方法
2015/04/07 Javascript
javascript实现简单的省市区三级联动
2015/05/14 Javascript
jquery实现输入框实时输入触发事件代码
2016/12/21 Javascript
AngularJS之ionic 框架下实现 Localstorage本地存储
2017/04/22 Javascript
React Native之ListView实现九宫格效果的示例
2017/08/02 Javascript
JavaScript定义及输出螺旋矩阵的方法详解
2017/12/01 Javascript
Bootstrap的aria-label和aria-labelledby属性实例详解
2018/11/02 Javascript
详细教你微信公众号正文页SVG交互开发技巧
2019/07/25 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
让IDE识别webpack的别名alias的实现方法
2020/05/06 Javascript
Python入门篇之函数
2014/10/20 Python
python3实现ftp服务功能(服务端 For Linux)
2017/03/24 Python
关于Python中空格字符串处理的技巧总结
2017/08/10 Python
Python单例模式的两种实现方法
2017/08/14 Python
Python+matplotlib实现华丽的文本框演示代码
2018/01/22 Python
简单了解django缓存方式及配置
2019/07/19 Python
Flask 上传自定义头像的实例详解
2020/01/09 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
Python爬虫之Selenium警告框(弹窗)处理
2020/12/04 Python
使用HTML5原生对话框元素并轻松创建模态框组件
2019/03/06 HTML / CSS
全球第二大家装零售商:Lowe’s
2018/01/13 全球购物
建议书怎么写
2014/03/12 职场文书
商务日语专业毕业生自荐信
2014/03/27 职场文书
合伙协议书
2014/04/23 职场文书
期末个人总结范文
2015/02/13 职场文书
南京南京观后感
2015/06/02 职场文书
小学三年级数学教学反思
2016/02/16 职场文书
2016年小学圣诞节活动总结
2016/03/31 职场文书
JS 4个超级实用的小技巧 提升开发效率
2021/10/05 Javascript
SpringBoot中HttpSessionListener的简单使用方式
2022/03/17 Java/Android