RxJS体验

RxJS体验

换一种思路来解决异步问题,最近在工作中遇到一个向后端轮询,查询桌面客服端是否启动的问题,使用RxJS来处理复杂的异步流程,真香!

几乎所有的网页应用都是异步的,微任务,宏任务,动画,事件回调队列......

  1. 脚本加载
  2. 播放器
  3. 数据访问
  4. 动画
  5. DOM事件

传统异步编程存在的问题,这些也是RxJS能处理的问题

  1. 异步编程中的状态(state)是难以追踪的
  2. 使用回调时,try...catch语法基本是没用的
  3. 如果你监听了一个事件却忘记了销毁它,很容易造成的内存泄露

如何用RxJs来实现

现要实现的请求需求如下

  1. 轮询时间7s
  2. 每间隔1s一次;
  3. 若有一次请求成功中止轮询,返回成功结果
  4. 10秒内未成功中止轮询,返回失败结果

如果使用Promise

// 1秒间隔
function sleep (ms: number) {
    return new Promise((resolve,reject) => {
        setTimeout(() => reject(new Error('请求后1s内无响应')), ms)
    })
}

// 串行请求
async function tenToAjax() {
    for(let i = 0; i < 10; i++){
        try {
            await Promise.race([fetch('url'), sleep(1000)])
            break
        } catch(err){
            console.log(err)
        }
    }
}

//10s时间
function ten () {
    return new Promise((reject) => {
        setTimeout(() => reject(new Error('10s内无响应')), 10000)
    })
}

const polling = Promise.race([tenToAjax(), ten()])
polling.then(v => console.log(v)).catch(e => console.log(e));

如果使用RxJS

import {  switchMap, filter, take, timeout } from 'rxjs/operators';
import { Observable, of, Subject, interval } from 'rxjs';

// 10s轮询函数,检查客户端是否启动
function pollingIsOpenClient(uid: string) {
    const getPollingDate$ = interval(1000).pipe(
        switchMap(() => getIsOpenClient(uid)),
        filter((res: any) => res.body.launchId === uid),
        take(1),
        timeout(10000)
    );
    return getPollingDate$;
}

利用RxJS操作符能函数式的解决复杂的异步流程,从我一个RxJS新手来说优点很多

  • 代码更简洁,声明式的代码可读性也更好
  • 使用纯函数来产生数据流(异步或同步),没有共享的代码,RxJS会将需要的状态隔离起来,如果有问题也更容易定位

缺点也有,不过还是香

  • 上手有一定难度
  • 上百个操作符要完成掌握还是需要一些时间

你可能感兴趣的:(RxJS体验)