使用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对象属性个数的示例代码
Nov 21 Javascript
Javascript学习笔记之 函数篇(一) : 函数声明和函数表达式
Jun 24 Javascript
JS实现网页表格自动变大缩小的方法
Mar 09 Javascript
JavaScript实现点击按钮字体放大、缩小
Feb 29 Javascript
Javascript的无new构建实例详解
May 15 Javascript
利用css+原生js制作简单的钟表
Apr 07 Javascript
原生JS实现图片左右轮播
Dec 30 Javascript
vue里input根据value改变背景色的实例
Sep 29 Javascript
Vue路由切换页面不更新问题解决方案
Jul 10 Javascript
谈谈JavaScript令人迷惑的==与+
Aug 31 Javascript
关于ES6尾调用优化的使用
Sep 11 Javascript
js基于canvas实现时钟组件
Feb 07 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函数间的参数传递(值传递/引用传递)
2013/09/23 PHP
修改apache配置文件去除thinkphp url中的index.php
2014/01/17 PHP
php中各种定义变量的方法小结
2017/10/18 PHP
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
JS 添加网页桌面快捷方式的代码详细整理
2012/12/27 Javascript
Javascript的时间戳和php的时间戳转换注意事项
2013/04/12 Javascript
jquery获取选中的文本和值的方法
2014/07/08 Javascript
原生JS实现响应式瀑布流布局
2015/04/02 Javascript
jquery拖拽排序简单实现方法(效果增强版)
2016/02/16 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
js实现表单及时验证功能 用户信息立即验证
2016/09/13 Javascript
bootstrap动态添加面包屑(breadcrumb)及其响应事件的方法
2017/05/25 Javascript
ES6中的Promise代码详解
2017/10/09 Javascript
详解如何使用PM2将Node.js的集群变得更加容易
2017/11/15 Javascript
vue props传值失败 输出undefined的解决方法
2018/09/11 Javascript
用webpack4开发小程序的实现方法
2019/06/04 Javascript
Python中删除文件的程序代码
2011/03/13 Python
python 控制语句
2011/11/03 Python
详解Django框架中用context来解析模板的方法
2015/07/20 Python
python基础之包的导入和__init__.py的介绍
2018/01/08 Python
Numpy 改变数组维度的几种方法小结
2018/08/02 Python
python实现ID3决策树算法
2018/08/29 Python
Django 多表关联 存储 使用方法详解 ManyToManyField save
2019/08/09 Python
python控制台实现tab补全和清屏的例子
2019/08/20 Python
Django中使用haystack+whoosh实现搜索功能
2019/10/08 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
2019/12/23 Python
Python 读取WAV音频文件 画频谱的实例
2020/03/14 Python
python nohup 实现远程运行不宕机操作
2020/04/16 Python
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
2018/02/07 HTML / CSS
英国大码女性时装零售商:Evans
2018/08/29 全球购物
小学毕业感言50字
2014/02/16 职场文书
活动总结怎么写啊
2014/05/07 职场文书
2014年保育员个人工作总结
2014/12/02 职场文书
2015年小学财务工作总结
2015/07/20 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书
Qt数据库应用之实现图片转pdf
2022/06/01 Java/Android