使用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 相关文章推荐
JS 动态加载脚本的4种方法
May 05 Javascript
根据IP的地址,区分不同的地区,查看不同的网站页面的js代码
Feb 26 Javascript
利用jq让你的div居中的好方法分享
Nov 21 Javascript
javascript:void(0)是什么意思及href=#与href=javascriptvoid(0)的区别
Nov 13 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
May 28 Javascript
Javascript中字符串replace方法的第二个参数探究
Dec 05 Javascript
AngularJS中的缓存使用
Jan 11 Javascript
JS中showModalDialog关闭子窗口刷新主窗口用法详解
Mar 25 Javascript
VUE实现图片验证码功能
Nov 18 Javascript
webpack3.0升级4.0的方法步骤
Apr 02 Javascript
原生js+canvas实现下雪效果
Aug 02 Javascript
vue 自定义的组件绑定点击事件
Apr 21 Vue.js
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 IP及IP段进行访问限制的代码
2008/12/17 PHP
php 需要掌握的东西 不做浮躁的人
2009/12/28 PHP
php分页思路以及在ZF中的使用
2012/05/30 PHP
php实现递归抓取网页类实例
2015/04/03 PHP
yii2框架中使用下拉菜单的自动搜索yii-widget-select2实例分析
2016/01/09 PHP
将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
2016/03/03 PHP
PHP设计模式(七)组合模式Composite实例详解【结构型】
2020/05/02 PHP
javascript event 事件解析
2011/01/31 Javascript
jQuery的attr与prop使用介绍
2013/10/10 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
js实现C#的StringBuilder效果完整实例
2015/12/22 Javascript
微信小程序 表单Form实例详解(附源码)
2016/12/22 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
JS实现css hover操作的方法示例
2017/04/07 Javascript
Node.js自定义实现文件路由功能
2017/09/22 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
vue cli构建的项目中请求代理与项目打包问题
2018/02/26 Javascript
微信小程序用户拒绝授权的处理方法详解
2019/09/20 Javascript
JS实现“全选”和&quot;全不选&quot;功能代码实例
2020/02/06 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
Python EOL while scanning string literal问题解决方法
2020/09/18 Python
python 日志增量抓取实现方法
2018/04/28 Python
django反向解析和正向解析的方式
2018/06/05 Python
在python3中pyqt5和mayavi不兼容问题的解决方法
2019/01/08 Python
python修改文件内容的3种方法详解
2019/11/15 Python
Python 时间戳之获取整点凌晨时间戳的操作方法
2020/01/28 Python
一款简洁的纯css3代码实现的动画导航
2014/10/31 HTML / CSS
美国糖果店:Sugarfina
2019/02/21 全球购物
简述数据库的设计过程
2015/06/22 面试题
Internet主要有哪些网络群组成
2015/12/24 面试题
大专毕业生简历的自我评价
2013/10/20 职场文书
校园联欢晚会主持词
2014/03/17 职场文书
亲子运动会的活动方案
2014/08/17 职场文书
商品陈列协议书
2014/09/29 职场文书
开学典礼观后感
2015/06/15 职场文书
军训结束新闻稿
2015/07/17 职场文书