VIP用户交流群:462197261 收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
在线客服:78895949
tonglan
  • 当前位置:
  • 使用RxJS更优雅地进行定时请求详析

    在用 Angular 做项目的时候,遇到了一个有点麻烦的问题。具体问题如下:

    轮循请求某个接口,如何保证接口返回的数据与请求的顺序相同?

    实际的业务场景是这样的:前端需要轮循请求后端接口获取文件处理进度,并在前端用进度条展示。如下方所示:

    首先想到的肯定是使用 setTimeout 或者 setInterval 进行定时请求。然而结果有点诡异,进度条的变化不是递增,而是有快有慢,比如 30%,20%,50%,40%这样。仔细一想也知道问题出在哪,异步请求的结果并不是按顺序返回的。

    我在之前的工作中还没有遇到过这类需求,所以我并不是很清楚如果用传统方式应该如何解决。然而很庆幸的是 RxJS 正好擅长处理这样的问题。我立即翻了一下文档,interval 操作符可以处理定时任务,而且更强大的是返回结果也是有顺序的。

    interval(period: 0 = 0, scheduler: SchedulerLike = async): Observable<number>

    首先看一下 interval 的说明:

    创建一个可观察对象,在规定的调度程序中,以规定的时间间隔发出连续的数值。

    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 确实是一个非常强大的工具库,尤其处理异步交互真的是省时省力,但是国内技术文章偏少,遇到疑难问题还需要查阅国外文章。欢迎大家评论交流。

    好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对北冥有鱼的支持。

    您可能感兴趣的文章:

    • jQuery图片切换插件jquery.cycle.js使用示例
    • RxJS的入门指引和初步应用
    • 如何用RxJS实现Redux Form
    • 关于RxJS Subject的学习笔记
    • Angular搜索场景中使用rxjs的操作符处理思路
    • Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
    • angular.js4使用 RxJS 处理多个 Http 请求
    • 学习RxJS之JavaScript框架Cycle.js

    广而告之:
    热门推荐:
    Bootstrap布局之栅格系统学习笔记

    1、简介 Bootstrap内置了一套响应式、移动设备优先的流式栅格系统,随着屏幕设备或视口(viewport)尺寸的增加,系统会自动分为最多12列。它包含了易于使用的预定义classe,还有强大的mixin用于生成更具语义的布局。 2、栅格选项 bootstrap3.x使用了四种栅格选项来形成栅格系···

    详解用vue.js和laravel实现微信授权登陆

    在laravel框架我们使用安正超的package 网址:https://easywechat.org/ 有专门的针对laravel的安装包,请参见如下网址:https://github.com/overtrue/laravel-wechat 下面来说说具体的安装: 1.安装package composer require overtrue/wechat 2.在app/config/app.php 中注册 ···

    织梦内容页,列表页,首页调用文章tag带url链接的方法

    织梦调用文章指定tag标签的方法,话不多说直接上代码: 第一种: 只调用tag标签中的文字,不带url链接 [field:id function=GetTags(@me)/] 这种方法有个弊端,就是调用出来的tag和发布文章时写入的tag完全一样 比如我们写入的是“网站建设,网站开发,网···

    destoon数据库表说明汇总

    destoon数据库表说明汇总如下,供二次开发人员查询: 表名  注释 destoon_404 404 日志 destoon_ad 广告 destoon_ad_place 广告位 destoon_admin 管理员 destoon_admin_log 管理日志 destoon_alert 贸易提醒 destoon_announce 公告 destoon_a···

    HTML5 文件域+FileReader 分段读取文件并上传到服务器

    说明:使用Ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续Ajax请求会使后台崩溃,获取InputStream中数据会为空,尤其在Google浏览器测试过程中。 1.简单分段读取文件为Blob,ajax上传到服务器 <div class="container"> <div class=&q···

    tsconfig.json配置详解

    概述 如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。 tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。 一个项目可以通过以下方式之一来编译: 使用tsconfig.json 不带任何输入文件的情况下调用tsc,编译器会从当···

    php中用socket模拟http中post或者get提交数据的示例代码

    废话不多说。直接上代码:sock_post.php:复制代码 代码如下:<?phpfunction sock_post($url, $data='') {  $url = parse_url($url);  $url['scheme'] || $url['scheme'] = 'http';  $url['host'] || $url['host'] = $_SERVER['HTTP_HOST'];  $url[···

    ThinkPHP中调用PHPExcel的实现代码

    核心代码: //引入PHPExcel vendor('PHPExcel.PHPExcel'); // Create new PHPExcel object $objPHPExcel = new PHPExcel(); //设置文档属性 $objPHPExcel->getProperties() ->setCreator("web100.cc") ->setLastModifiedBy("web100.cc") ->setTitle···

    PHP设计模式之适配器模式定义与用法详解

    本文实例讲述了PHP设计模式之适配器模式定义与用法。分享给大家供大家参考,具体如下: 适配器很容易理解, 大多数人家庭都有手机转接器, 用来为移动电话充电,这就是一种适配器. 如果只有USB接头, 就无法将移动电话插到标准插座上. 实际上, 必须使用一个适配器, 一端接USB插头, ···

    inquirer.js一个用户与命令行交互的工具详解

    写在前面: 开始通过npm init 创建package.json的时候就有大量与用户的交互(当然也可以通过参数来忽略输入);而现在大多数工程都是通过脚手架来创建的,使用脚手架的时候最明显的就是与命令行的交互,如果想自己做一个脚手架或者在某些时候要与用户进行交互,这个时候就不得不···