使用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和注册表脚本实现右键收藏Web页选中文本
Jan 28 Javascript
MooBox 基于Mootools的对话框插件
Jan 20 Javascript
JS中不为人知的五种声明Number的方式简要概述
Feb 22 Javascript
script标签属性用type还是language
Jan 21 Javascript
判断输入的字符串是否是日期格式的简单方法
Jul 11 Javascript
JS Select下拉框(支持输入模糊查询)
Feb 04 Javascript
js实现短信发送倒计时功能(正则验证)
Feb 10 Javascript
vue2 自定义动态组件所遇到的问题
Jun 08 Javascript
详解原生js实现offset方法
Jun 15 Javascript
使用Angular CLI进行单元测试和E2E测试的方法
Mar 24 Javascript
vue项目中应用ueditor自定义上传按钮功能
Apr 27 Javascript
vue使用Font Awesome的方法步骤
Feb 26 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求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
PHP微商城开源代码实例
2019/03/27 PHP
php实现微信小程序授权登录功能(实现流程)
2019/11/13 PHP
WEB 浏览器兼容 推荐收藏
2010/05/14 Javascript
JavaScript 一道字符串分解的题目
2011/08/03 Javascript
JavaScript中合并数组的N种方法
2014/09/16 Javascript
AngularJS ngModel实现指令与输入直接的数据通信
2016/09/21 Javascript
Vue.js项目模板搭建图文教程
2017/09/20 Javascript
vue单页面打包文件大?首次加载慢?nginx带你飞,从7.5M到1.3M蜕变过程(推荐)
2018/01/16 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
vue.js中proxyTable 转发请求的实现方法
2018/09/20 Javascript
nuxt中使用路由守卫的方法步骤
2019/01/27 Javascript
jquery实现手风琴案例
2020/05/04 jQuery
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
Python实现Linux下守护进程的编写方法
2014/08/22 Python
Python使用正则表达式抓取网页图片的方法示例
2017/04/21 Python
Python编程之黑板上排列组合,你舍得解开吗
2017/10/30 Python
python实现人人自动回复、抢沙发功能
2018/06/08 Python
用pycharm开发django项目示例代码
2018/10/24 Python
Python及Pycharm安装方法图文教程
2019/08/05 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
Python数据处理篇之Sympy系列(五)---解方程
2019/10/12 Python
python几种常用功能实现代码实例
2019/12/25 Python
pytorch逐元素比较tensor大小实例
2020/01/03 Python
对Keras中predict()方法和predict_classes()方法的区别说明
2020/06/09 Python
Pycharm连接gitlab实现过程图解
2020/09/01 Python
荷兰超市:DEEN
2018/03/14 全球购物
英国当代时尚和街头服饰店:18montrose
2018/12/15 全球购物
打架检讨书100字
2014/01/08 职场文书
5.1手机促销活动
2014/01/17 职场文书
工伤事故赔偿协议书(标准)
2014/09/29 职场文书
党支部2014年度工作总结
2014/12/04 职场文书
先进单位申报材料
2014/12/25 职场文书
市场部岗位职责
2015/02/12 职场文书
2015年教师教学工作总结
2015/04/28 职场文书
活着观后感
2015/06/03 职场文书