使用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 相关文章推荐
ppk谈JavaScript style属性
Oct 10 Javascript
JavaScript简单实现鼠标拖动选择功能
Mar 06 Javascript
jquery-syntax动态语法着色示例代码
May 14 Javascript
javascript生成随机数方法汇总
Nov 12 Javascript
js实现div在页面拖动效果
May 04 Javascript
批量下载对路网图片并生成html的实现方法
Jun 07 Javascript
BOM系列第一篇之定时器setTimeout和setInterval
Aug 17 Javascript
Bootstrap基本组件学习笔记之input输入框组(9)
Dec 07 Javascript
基于javascript的Form表单验证
Dec 29 Javascript
微信小程序 本地数据存储实例详解
Apr 13 Javascript
js如何编写简单的ajax方法库
Aug 02 Javascript
微信小程序嵌入腾讯视频源过程详解
Aug 08 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
如何实现给定日期的若干天以后的日期
2006/10/09 PHP
实用函数7
2007/11/08 PHP
PHP获取当前文件所在目录 getcwd()函数
2009/05/13 PHP
PHP和Mysqlweb应用开发核心技术-第1部分 Php基础-2 php语言介绍
2011/07/03 PHP
phpmailer发送gmail邮件实例详解
2013/06/24 PHP
IE Firefox 使用自定义标签的区别
2009/10/15 Javascript
javascript instanceof 与typeof使用说明
2010/01/11 Javascript
Javascript 实现TreeView CheckBox全选效果
2010/01/11 Javascript
jquery插件制作教程 txtHover
2012/08/17 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
jQuery的animate函数学习记录
2014/08/08 Javascript
java必学必会之static关键字
2015/12/03 Javascript
深入理解node exports和module.exports区别
2016/06/01 Javascript
javascript类型系统——日期Date对象全面了解
2016/07/13 Javascript
基于jQuery实现的打字机效果
2017/01/16 Javascript
jQuery实现级联下拉框实战(5)
2017/02/08 Javascript
Javascript查看大图功能代码实现
2020/05/07 Javascript
详解JSON.stringify()的5个秘密特性
2020/05/26 Javascript
vue-admin-template配置快捷导航的代码(标签导航栏)
2020/09/04 Javascript
Vue axios 跨域请求无法带上cookie的解决
2020/09/08 Javascript
Python pandas常用函数详解
2018/02/07 Python
符合语言习惯的 Python 优雅编程技巧【推荐】
2018/09/25 Python
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
2019/04/03 Python
Python ckeditor富文本编辑器代码实例解析
2020/06/22 Python
Python实现像awk一样分割字符串
2020/09/15 Python
python 基于PYMYSQL使用MYSQL数据库
2020/12/24 Python
CSS3只让背景图片旋转180度的实现示例
2021/03/09 HTML / CSS
英国的领先快速时尚零售商:In The Style
2019/03/25 全球购物
求职简历自荐信范文
2013/10/21 职场文书
最新结婚典礼主持词
2014/03/14 职场文书
教师思想工作总结2015
2015/05/13 职场文书
2015暑期爱心支教策划书
2015/07/14 职场文书
证婚人婚礼致辞
2015/07/28 职场文书
如何书写邀请函?
2019/06/24 职场文书
mybatis调用sqlserver存储过程返回结果集的方法
2021/05/08 SQL Server
JS数组去重详情
2021/11/07 Javascript