使用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入门教程(5) js Screen屏幕对象
Jan 31 Javascript
jquery 防止表单重复提交代码
Jan 21 Javascript
ANT 压缩(去掉空格/注释)JS文件可提高js运行速度
Apr 15 Javascript
Google Maps API地图应用示例分享
Oct 23 Javascript
深入解析Backbone.js框架的依赖库Underscore.js的作用
May 07 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
May 21 Javascript
JavaScript接口的实现三种方式(推荐)
Jun 14 Javascript
解析预加载显示图片艺术
Dec 05 Javascript
jQuery Validate验证框架详解(推荐)
Dec 17 Javascript
JavaScript框架Angular和React深度对比
Nov 20 Javascript
React Hooks的深入理解与使用
Nov 12 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
May 23 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
关于页面优化和伪静态
2009/10/11 PHP
QueryPath PHP 中的jQuery
2010/04/11 PHP
php面向对象中static静态属性与方法的内存位置分析
2015/02/08 PHP
php返回相对时间(如:20分钟前,3天前)的方法
2015/04/14 PHP
屏蔽PHP默认设置中的Notice警告的方法
2016/05/20 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
javascript 对象比较实现代码
2009/04/27 Javascript
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
两种方法实现在HTML页面加载完毕后运行某个js
2014/06/16 Javascript
jquery阻止后续事件只执行第一个事件
2014/07/24 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
Nodejs--post的公式详解
2017/04/29 NodeJs
vue父组件向子组件传递多个数据的实例
2018/03/01 Javascript
Bootstrap Table实现定时刷新数据的方法
2018/08/13 Javascript
vue 解决文本框被键盘遮住的问题
2019/11/06 Javascript
Vue 实现简易多行滚动&quot;弹幕&quot;效果
2020/01/02 Javascript
three.js利用射线Raycaster进行碰撞检测
2020/03/12 Javascript
Taro UI框架开发小程序实现左滑喜欢右滑不喜欢效果的示例代码
2020/05/18 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
python的paramiko模块实现远程控制和传输示例
2017/10/13 Python
python的变量与赋值详细分析
2017/11/08 Python
python实现随机漫步算法
2018/08/27 Python
pandas删除指定行详解
2019/04/04 Python
pytorch查看torch.Tensor和model是否在CUDA上的实例
2020/01/03 Python
Selenium webdriver添加cookie实现过程详解
2020/08/12 Python
python爬虫scrapy框架之增量式爬虫的示例代码
2021/02/26 Python
html5 canvas实现给图片添加平铺水印
2019/08/20 HTML / CSS
贝嫂喜欢的婴儿品牌,个性化的婴儿礼物:My 1st Years
2017/11/19 全球购物
区域销售经理岗位职责
2013/12/10 职场文书
交通事故协议书范文
2014/04/16 职场文书
锦旗标语大全
2014/06/23 职场文书
文明单位汇报材料
2014/12/24 职场文书
优秀护士事迹材料
2014/12/25 职场文书
Python可变集合和不可变集合的构造方法大全
2021/12/06 Python
Python实现双向链表基本操作
2022/05/25 Python