使用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 相关文章推荐
jQuery EasyUI API 中文文档 - Tree树使用介绍
Nov 19 Javascript
两种方法实现文本框输入内容提示消失
Mar 17 Javascript
jquery实现div阴影效果示例代码
Sep 16 Javascript
使用jQuery将多条数据插入模态框的实现代码
Oct 08 Javascript
详解JavaScript的Polymer框架中的通知交互
Jul 29 Javascript
浅谈Javascript中的Label语句
Dec 14 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
用JavaScript和jQuery实现瀑布流
Mar 19 Javascript
vuex实现登录状态的存储,未登录状态不允许浏览的方法
Mar 09 Javascript
vue的toast弹窗组件实例详解
May 14 Javascript
原生js实现照片墙效果
Oct 13 Javascript
Javascript的promise,async和await的区别详解
Mar 24 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
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
人大复印资料处理程序_查询篇
2006/10/09 PHP
给初学PHP的5个入手程序
2006/11/23 PHP
php中文字母数字验证码实现代码
2008/04/25 PHP
centos 5.6 升级php到5.3的方法
2011/05/14 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
CI框架附属类用法分析
2018/12/26 PHP
php + WebUploader实现图片批量上传功能
2019/05/06 PHP
Laravel框架Eloquent ORM修改数据操作示例
2019/12/03 PHP
Javascript 面向对象 继承
2010/05/13 Javascript
基于jQuery的自动完成插件
2011/02/03 Javascript
functional继承模式 摘自javascript:the good parts
2011/06/20 Javascript
Javascript面向对象扩展库代码分享
2012/03/27 Javascript
原生JS实现拖拽图片效果
2020/08/27 Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
2016/02/16 Javascript
JavaScript实现简单的树形菜单效果
2017/06/23 Javascript
vue组件父与子通信详解(一)
2017/11/07 Javascript
javascript如何实现create方法
2019/11/04 Javascript
[01:01:01]完美世界DOTA2联赛循环赛 GXR vs FTD BO2第一场 10.29
2020/10/29 DOTA
Python的time模块中的常用方法整理
2015/06/18 Python
实例讲解Python编程中@property装饰器的用法
2016/06/20 Python
python 获取指定文件夹下所有文件名称并写入列表的实例
2018/04/23 Python
django2+uwsgi+nginx上线部署到服务器Ubuntu16.04
2018/06/26 Python
linux查找当前python解释器的位置方法
2019/02/20 Python
python使用Plotly绘图工具绘制柱状图
2019/04/01 Python
Keras 使用 Lambda层详解
2020/06/10 Python
CSS3 text shadow字体阴影效果
2016/01/08 HTML / CSS
南非最大的花卉和送礼服务:NetFlorist
2017/09/13 全球购物
极简鞋类,赤脚的感觉:Lems Shoes
2019/08/06 全球购物
经贸日语专业个人求职信范文
2013/12/28 职场文书
骨干教师培训制度
2014/01/13 职场文书
电工工作职责范本
2014/02/22 职场文书
租房协议书范文
2014/08/20 职场文书
党员组织生活会发言材料
2014/10/17 职场文书
2019通用版导游词范本!
2019/08/07 职场文书
PO模式在selenium自动化测试框架的优势
2022/03/20 Python