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

  • 相关阅读:
    课堂练习
    日程管理测试用例
    日程管理APP的测试计划和测试矩阵
    日程管理Bug Report
    图书管理系统活动图
    团队如何做决定?
    课堂练习
    课堂练习(NABCD Model)
    课堂练习
    日程管理的测试计划和测试矩阵
  • 原文地址:https://www.cnblogs.com/nzbin/p/10956065.html
Copyright © 2011-2022 走看看