使用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中null与undefined分析
Jul 25 Javascript
Document对象内容集合(比较全)
Sep 06 Javascript
JS字符串函数扩展代码
Sep 13 Javascript
javascript中eval函数用法分析
Apr 25 Javascript
javascript实现网页背景烟花效果的方法
Aug 06 Javascript
javascript实现简单加载随机色方块
Dec 25 Javascript
JavaScript高级程序设计(第三版)学习笔记1~5章
Mar 11 Javascript
第四章之BootStrap表单与图片
Apr 25 Javascript
js输入框使用正则表达式校验输入内容的实例
Feb 12 Javascript
移动端web滚动分页的实现方法
May 05 Javascript
js生成word中图片处理方法
Jan 06 Javascript
JavaScript实现H5接金币功能(实例代码)
Feb 22 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 foreach循环使用详解与实例代码
2010/05/08 PHP
php数据库密码的找回的步骤
2011/01/12 PHP
php进行支付宝开发中return_url和notify_url的区别分析
2014/12/22 PHP
js 数组克隆方法 小结
2010/03/20 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
2012/12/27 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
图片img的src不变让浏览器重新加载实现方法
2013/03/29 Javascript
判断JS对象是否拥有某种属性的两种方式
2013/12/02 Javascript
js判断文本框剩余可输入字数的方法
2015/02/04 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
2016/07/27 Javascript
AngularJS 路由详解和简单实例
2016/07/28 Javascript
jquery实现网页定位导航
2016/08/23 Javascript
vue2.0 better-scroll 实现移动端滑动的示例代码
2018/01/25 Javascript
解决vue路由后界面没有变化,但是链接有的问题
2018/09/01 Javascript
vue 中使用 watch 出现了如下的报错的原因分析
2019/05/21 Javascript
js实现贪吃蛇小游戏
2019/10/29 Javascript
vue中上传视频或图片或图片和文字一起到后端的解决方法
2019/12/01 Javascript
Vue extend的基本用法(实例详解)
2019/12/09 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
解决iview table组件里的 固定列 表格不自适应的问题
2020/11/13 Javascript
Python是编译运行的验证方法
2015/01/30 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
2019/07/22 Python
python实现超市管理系统(后台管理)
2019/10/25 Python
python列表推导和生成器表达式知识点总结
2020/01/10 Python
全网最细 Python 格式化输出用法讲解(推荐)
2021/01/18 Python
借助HTML5 Canvas API制作一个简单的猜字游戏
2016/03/25 HTML / CSS
日本最大的眼镜购物网站:Oh My Glasses
2016/11/13 全球购物
Linux面试题LINUX系统类
2015/11/25 面试题
应届毕业生就业自荐信
2013/10/26 职场文书
外企办公室竞聘演讲稿
2013/12/29 职场文书
小学生期末评语
2014/04/21 职场文书
三八活动策划方案
2014/08/17 职场文书
自查自纠工作总结
2014/10/15 职场文书
电影红河谷观后感
2015/06/11 职场文书
详解Python自动化之文件自动化处理
2021/06/21 Python