RxJS 学习指南

# RxJS 简介

# 什么是 ReactiveX

ReactiveX 是一套采用响应式流的异步编程模式,
具体实现包括 RxJS、RxJava、RxSwift 等,
虽然这些实现的语言不同,但是核心思想和 API 都是相同的。
这个相同的部分就称之为 ReactiveX。

它能将离散的多个事件视为一个流来操控,

将事件/数据作为流传播,
流可以(通过操作符)进行各种变换(映射、采样、合并等)

# 什么是 RxJS

ReactiveX 的 JS 具体实现

它相当于事件版的 Lodash

# 为什么要用 RxJS

能用更少和清晰的代码完成异步业务

# 学习 RxJS

# 概览

  • 耗时:从入门到熟悉需要大约 15~30 小时(个人估计)
  • 难点:
    • 理解 Stream 范式
    • 熟悉 API 全貌并综合运用
  • 工具:

# 学习路线

  • 前置学习
    • 理解 RxJS 编程理念
      • 编程范式
        • functional programming
        • reactive programming
        • stream programming
      • 设计模式
        • 迭代器模式(事件流遍历机制)
        • 观察者模式(绑定机制)
    • (TypeScript 学习指南)
  • 学习 Rxjs
    • 掌握 RxJS 核心概念
      • Observable 及上下游
      • 多播操作符、Subject
      • Scheduler
    • 尝试 RxJS 所有(类型)的 API
      • 同类 API 之间的效果差异
      • 相同效果的流可以有多种实现方式
  • 题目/实战
    • 练习实现具体功能,加深理解
    • 结合 react/vue
  • 进阶
    • 实现一个自己的 Observable
    • 阅读 RxJS 源码实现
  • 迷思
    • 如何手动结束/关闭一个 Observable

# 资料

# 我的学习代码

# 关于 响应式编程

# RxJS 自学教材

# 实战

# RxJS 知识体系

# RxJS 主要概念

  • [Ob 相关]
    • Observable: 可被观测的/数据流序列(很多创建方式,如 timer、fromEvent 等)
    • operator: 操作符(对事件流进行形变,比如 map、merge 等)
  • [Sub 相关]
    • subscribe: 订阅方法(Observable 提供的)
      • Observer: 观察者/消费者方法集合(业务方法,传给 subscribe() 的)
    • Subscription: 订阅关系(subscribe 返回的)
      • unsubscribe: 结束订阅方法(Subscription 提供的)
  • Subject: 多播的 Observable(可以作为 Observable 和 Subscription 的中间层)
  • Scheduler:调度器
  • Cold VS Hot Observable
    • Cold:多次订阅产生多个独立的事件流(用途例如:interval
    • Hot:多次订阅共享同一个事件流(用途例如:fromEventSubject

# RxJS 典型代码

# RxJS 基本用法

# 伪代码

// * 注册 事件流
Ob = Observable
  // * (可选的)操作符 对原始事件流进行加工处理
  .operators()

// * 订阅 (支持多种写法)
Subscription = Ob.subscribe( next?: (e)=>{}, error?: (e)=>{}, complete?: ()=>{} )
// * 订阅 (支持多种写法)
Subscription = Ob.subscribe( Observer{
  next(e) {}
  error(e) {}
  complete() {}
})

// * 取消订阅
Subscription.unsubscribe()

# 具体代码 v5

// Node.js

import { Observable } from 'rxjs';

const ob$ = Observable.interval(500).map((e) => e * 2);

const sub$ = ob$.subscribe((e) => console.warn(e));

setTimeout(() => sub$.unsubscribe(), 3000);

# 具体代码 v6

// Node.js

import { interval } from 'rxjs';
import { map } from 'rxjs/operators';

const ob$ = interval(500).pipe(map((e) => e * 2));

const sub$ = ob$.subscribe((e) => console.warn(e));

setTimeout(() => sub$.unsubscribe(), 3000);

# RxJS 实用代码

// * interval of requestAnimationFrame, tick frame time (ms)
const rafInterval$ = () =>
  of(Date.now(), animationFrameScheduler).pipe(
    map((start) => Date.now() - start),
    repeat(),
  );

# RxJS 相关

# RxJS 和 TypeScript

RxJS 源码是 TypeScript 写的,对 TS 支援度很不错

但目前还有些 bug:

// * 没有正确识别
pipe(publish()); // => Observable<any>

// * 需要手动指定 type
pipe(publish()) as ConnectableObservable<any>;

# RxJS 版本

截稿时 RxJS 最新的版本是 v6
v7 处于 alpha 中)
v6v5 的主要差别在于 API 名和语法

比如为了实现函数式调用风格,
操作符 do 重命名成了 tap (因为 do 是 JS 保留字)

新项目直接用 v6 即可
老项目也可以用兼容包升级

# 命名习惯

const myStream$ = interval(500);

流相关的命名一般用 $ 做后缀,是业界习惯,但也没有硬性规定。
(就像用 jQuery 会使用 $ 前缀,不用也不影响代码效果)