当前位置: 首页 > news >正文

Nestjs框架: 理解 RxJS响应式编程的核心概念与实践

概述

  • RxJS 是一个用于处理异步和基于事件编程的库,其核心理念是使用可观察序列(Observable Sequences)来构建程序逻辑
  • 你可以把它看作是处理事件的“lodash”,类似于 lodash 对数组和对象的操作,RxJS 则是对事件流的操作

1 )学习资源推荐

目前中文社区中有几个关于 RxJS 的文档网站可供参考:

  • cn.rx.js.org 官方文档,内容详尽,结构清晰;

  • rx.nodejs.cn 中文社区翻译版,适合中文用户;

  • rxjs.tech 翻译质量相对较高,推荐使用。

  • rxjs.dev 官网

  • 需要注意的是,文档中某些功能在文档中标记为划线

  • 表示这些方法可能已被弃用,或在未来的版本中不再支持

2 )核心概念解析

  • 官方介绍中提到:RxJS 是一个使用可观察序列编写异步和基于事件程序的库

  • 这句话可能初看有些晦涩,但其核心聚焦点在于两个方面:

    • 可观察序列(Observable Sequences)
    • 异步/事件处理能力
  • 为了更好地理解 RxJS,我们需要先了解其几个核心类型:

    • Observable(可观察对象):类似于 Promise,但它可以发出多个值,而不是只能解决一次;
    • Observer(观察者):用于监听 Observable 发出的值;
    • Subject(主体):一种特殊的 Observable,用于广播事件;
    • Operators(操作符):如 map、filter、reduce 等,用于处理事件流;
    • Scheduler(调度器):控制异步任务的执行方式,属于进阶概念。
  • 这些核心类型和操作符构成了 RxJS 的基础,使得我们可以将异步事件当作集合一样进行操作和处理

3 )实践示例:从事件监听到流式处理

  • 我们以一个简单的 DOM 事件监听为例,来看看 RxJS 如何处理事件

  • 传统的写法是:

    document.addEventListener('click', () => {// 处理点击事件
    });
    
  • 而使用 RxJS 后:

    import { fromEvent } from 'rxjs';
    fromEvent(document, 'click').subscribe(() => { console.log('Clicked!') });
    
  • 这里的 fromEvent 返回一个 Observable,通过 subscribe 方法进行订阅

  • 你也可以传入一个 Observer 对象,它包含三个回调方法:

    • next():每次事件触发时调用;
    • error():发生错误时调用;
    • complete():流结束时调用。
  • 这种写法不仅结构清晰,而且支持链式调用,便于管理状态

4 )操作符与流式控制:Purity 与 Flow

4.1 Purity

  • Purity(纯净性) 是 RxJS 的一大优势,它允许我们使用纯函数来生成值
  • 创建一个不纯的函数,举例,通常会弄乱你的状态
    let count = 0;
    document.addEventListener('click', () => console.log(`Clicked ${++count} times`));
    
  • 例如,我们可以使用 scan 操作符来实现点击计数,可以隔离状态
    import { fromEvent, scan } from 'rxjs';
    import { scan } from 'rxjs/operators';fromEvent(document, 'click').pipe(scan((count) => count + 1, 0)).subscribe(count => console.log(`Clicked ${count} times`));
    
  • 在这个例子中,scan 类似于数组的 reduce 方法,每次点击都会将计数值递增,初始值是 0
  • 它可以把状态量在链式写法里面执行,不需要再外层单独定义了

4.2 Flow

Flow(流动) 是 RxJS 中另一个核心概念,它表示事件流的传递与变换
我们可以使用 pipe 函数将多个操作符串联起来,实现复杂的事件处理逻辑:
它把嵌套的函数调用变成了一种管道内参数传递的方式

下面是使用纯 JavaScript 实现“最多允许每秒单击一次”的方式:

let count = 0;
let rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener('click', () => {if (Date.now() - lastClick >= rate) {console.log(`Clicked ${++count} times`);lastClick = Date.now();}
});

使用 RxJS:

import { fromEvent, throttleTime, scan } from 'rxjs';fromEvent(document, 'click').pipe(throttleTime(1000),scan((count) => count + 1, 0)).subscribe((count) => console.log(`Clicked ${count} times`));
  • 这里本质上是一个节流操作,这里的 pipe 方法让代码更具有可读性
  • 将嵌套的函数调用转化为参数传递的方式,使得事件流的处理逻辑更加清晰
  • 操作符中的管道文档 operators#piping

5 ) Values 与值的处理

Values(值转换) 是 RxJS 中处理流中数据的方式
可以通过你的 observables 传来的值进行转换

以下是使用纯 JavaScript 来为每次单击增加当前鼠标 x 位置的方法

let count = 0;
const rate = 1000;
let lastClick = Date.now() - rate;
document.addEventListener('click', (event) => {if (Date.now() - lastClick >= rate) {count += event.clientX;console.log(count);lastClick = Date.now();}
});

使用 RxJS之后

import { fromEvent, throttleTime, map, scan } from 'rxjs';fromEvent(document, 'click').pipe(throttleTime(1000),map((event) => event.clientX),scan((count, clientX) => count + clientX, 0)).subscribe((count) => console.log(count));
  • 这里使用了 map 操作符提取事件中的值:

  • RxJS 提供了大量操作符

  • 这些操作符都可在官方文档的 Operators 分类中找到详细说明

6 ) 总结

RxJS 的几个核心概念

  • Observable、Observer、Subject、Operator、Scheduler
  • 如何使用 fromEvent 创建事件流
  • 如何通过 pipe 串联操作符处理事件流
  • 如何使用 scan、map、filter、throttleTime 等操作符进行事件处理
  • RxJS 与传统回调方式的区别:链式结构、状态管理、可维护性增强
http://www.xdnf.cn/news/1153441.html

相关文章:

  • 商业秘密视域下计算机软件的多重保护困境
  • 支付宝支付
  • day11 ADC
  • 论文略读: RASA: RANK-SHARING LOW-RANK ADAPTATION
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘sqlalchemy’问题
  • Linux内核设计与实现 - 第6章 内核数据结构
  • NX二次开发常用函数坐标转化UF_MTX4_csys_to_csys和UF_MTX4_vec3_multipl
  • 轻松学习C++:基本语法解析
  • 多线程 示例
  • leetcode_121 买卖股票的最佳时期
  • AWS Partner: Accreditation (Technical)
  • 轻松上手:从零开始启动第一个 Solana 测试节点
  • 综合实验--eNSP实验
  • TypeScript 泛型详解:从基础到实战应用
  • Linux中添加重定向(Redirection)功能到minishell
  • python网络爬虫之selenium库(二)
  • 【Web APIs】JavaScript 自定义属性操作 ② ( H5 自定义属性 )
  • 图片放大镜案例
  • Patch-wise Structural:一种引入局部统计特性的时序预测损失函数
  • CS231n-2017 Lecture3线性分类器、最优化笔记
  • QT窗口(7)-QColorDiag
  • [spring6: AspectJAdvisorFactory AspectJProxyFactory]-源码解析
  • Linux C 信号操作
  • “外卖大战”正在改变国内“大零售”
  • 图解系统-小林coding笔记
  • 骑行邂逅LV巨轮,VELO维乐Angel Rise坐垫与时尚超适配
  • YOLOv11改进 | RFAConv重塑空间注意力助力性能提升
  • 开关电源和线性电源Multisim电路仿真实验汇总——硬件工程师笔记
  • 使用UV管理FastAPI项目
  • HOT100——动态规划篇Leetcode221. 最大正方形