使用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 While 循环基础教程
Apr 05 Javascript
读jQuery之五(取DOM元素)
Jun 20 Javascript
javascript中的括号()用法小结
Apr 14 Javascript
javascript随机显示背景图片的方法
Jun 18 Javascript
浅析jquery与checkbox的checked属性的问题
Apr 27 Javascript
jQuery Raty 一款不错的星级评分插件
Aug 24 Javascript
jquery 动态增加,减少input表单的简单方法(必看)
Oct 12 Javascript
ionic中列表项增加和删除的实现方法
Jan 22 Javascript
javaScript字符串工具类StringUtils详解
Dec 08 Javascript
利用Node.js批量抓取高清妹子图片实例教程
Aug 02 Javascript
vue .js绑定checkbox并获取、改变选中状态的实例
Aug 24 Javascript
Node.js学习之内置模块fs用法示例
Jan 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,ASP.JAVA,JAVA代码格式化工具整理
2010/06/15 PHP
php环境套包 dedeampz 伪静态设置示例
2014/03/26 PHP
PHP错误WARNING: SESSION_START() [FUNCTION.SESSION-START]解决方法
2014/05/04 PHP
php smarty truncate UTF8乱码问题解决办法
2014/06/13 PHP
高性能PHP框架Symfony2经典入门教程
2014/07/08 PHP
Cygwin中安装PHP方法步骤
2015/07/04 PHP
window.addeventjs事件驱动函数集合addEvent等
2008/02/19 Javascript
JQUERY dialog的用法详细解析
2013/12/19 Javascript
JavaScript的21条基本知识点
2014/03/04 Javascript
使用jQuery.wechat构建微信WEB应用
2014/10/09 Javascript
jquery中JSON的解析方式
2015/03/16 Javascript
JS实现选项卡实例详解
2015/11/17 Javascript
JQuery在循环中绑定事件的问题详解
2016/06/02 Javascript
Three.js学习之文字形状及自定义形状
2016/08/01 Javascript
vue2.0使用Sortable.js实现的拖拽功能示例
2017/02/21 Javascript
基于JS实现网页中的选项卡(两种方法)
2017/06/16 Javascript
React Native第三方平台分享的实例(Android,IOS双平台)
2017/08/04 Javascript
vue axios 二次封装的示例代码
2017/12/08 Javascript
微信小程序如何像vue一样在动态绑定类名
2018/04/17 Javascript
jquery.pagination.js分页使用教程
2018/10/23 jQuery
Nodejs让异步变成同步的方法
2019/03/02 NodeJs
利用Python中的pandas库对cdn日志进行分析详解
2017/03/07 Python
git使用.gitignore设置不生效或不起作用问题的解决方法
2017/06/01 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
用python代码将tiff图片存储到jpg的方法
2018/12/04 Python
Django之模型层多表操作的实现
2019/01/08 Python
Python爬虫运用正则表达式的方法和优缺点
2019/08/25 Python
如何用Matplotlib 画三维图的示例代码
2020/07/28 Python
Levi’s美国官网:美国著名的牛仔裤品牌
2016/08/19 全球购物
几个人围成一圈的问题
2013/09/26 面试题
27个经典Linux面试题及答案,你知道几个?
2014/03/11 面试题
校园招聘策划书
2014/01/09 职场文书
最常使用的求职信
2014/05/25 职场文书
信用卡收入证明范本
2015/06/12 职场文书
毕业证明书
2015/06/19 职场文书
MYSQL事务的隔离级别与MVCC
2022/05/25 MySQL