使用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中的Location地址对象
Jan 16 Javascript
CSS+Jquery实现页面圆角框方法大全
Dec 24 Javascript
AngularJS入门教程(零):引导程序
Dec 06 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
Apr 01 Javascript
浅谈jquery之on()绑定事件和off()解除绑定事件
Oct 26 Javascript
Bootstrap的class样式小结
Dec 01 Javascript
浅谈js数组和splice的用法
Dec 04 Javascript
简单理解js的prototype属性及使用
Dec 07 Javascript
Node.js学习之查询字符串解析querystring详解
Sep 28 Javascript
vue项目中使用fetch的实现方法
Apr 25 Javascript
Vue多环境代理配置方法思路详解
Jun 21 Javascript
微信小程序实现音乐播放页面布局
Dec 11 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中Cannot send session cache limiter 的问题的方法
2007/04/27 PHP
thinkphp缓存技术详解
2014/12/09 PHP
PHP程序中使用adodb连接不同数据库的代码实例
2015/12/19 PHP
PHP编程实现微信企业向用户付款的方法示例
2017/07/26 PHP
PHP如何根据文件头检测文件类型实例代码
2018/10/14 PHP
10个基于Jquery的幻灯片插件教程
2010/10/29 Javascript
js或jquery实现页面打印可局部打印
2014/03/27 Javascript
indexOf 和 lastIndexOf 使用示例介绍
2014/09/02 Javascript
关于JS中prototype的理解
2015/09/07 Javascript
Javascript中的数据类型之旅
2015/10/18 Javascript
浏览器兼容性问题大汇总
2015/12/17 Javascript
如何判断出一个js对象是否一个dom对象
2016/11/24 Javascript
JavaScript实现前端分页控件
2017/04/19 Javascript
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
详解JavaScript中操作符和表达式
2018/09/12 Javascript
Vue项目从webpack3.x升级webpack4不完全指南
2019/04/28 Javascript
element-ui中dialog弹窗关闭按钮失效的解决
2020/09/22 Javascript
实例讲解Python的函数闭包使用中应注意的问题
2016/06/20 Python
python实现车牌识别的示例代码
2019/08/05 Python
Python使用pymysql模块操作mysql增删改查实例分析
2019/12/19 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
Nginx+Uwsgi+Django 项目部署到服务器的思路详解
2020/05/08 Python
python 5个顶级异步框架推荐
2020/09/09 Python
英国度假别墅预订:Sykes Cottages
2017/06/12 全球购物
学生拾金不昧表扬信
2014/01/21 职场文书
厨师长岗位职责
2014/03/02 职场文书
幼儿评语大全
2014/04/30 职场文书
岗位安全生产责任书
2014/07/28 职场文书
2015年八一建军节演讲稿
2015/03/19 职场文书
大队委员竞选稿
2015/11/20 职场文书
python中的None与NULL用法说明
2021/05/25 Python
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏
Java多线程并发FutureTask使用详解
2022/06/28 Java/Android