Vanilla JavaScript 的 RxJS 基础课程
1. 什么是响应式编程
响应式编程处理的是随时间变化的数据流。
鼠标点击是事件,输入框打字是事件,HTTP 响应是异步事件。核心思路:别反复轮询 "数据到了没",数据来的时候你直接响应就行。
2. 什么是 RxJS
RxJS 是个 JavaScript 库,用 Observable 来组合异步和事件驱动的逻辑。
快速安装
使用 npm:
npm install rxjs使用 CDN:
<script src="https://unpkg.com/rxjs@7/dist/bundles/rxjs.umd.min.js"></script>Vanilla JS 基础结构
目录就三个文件:index.html、app.js、styles.css(可选)。
3. Observable
Observable 是数据源,可以在时间轴上发出 0 个、1 个或多个值。
const { of, from, interval } = rxjs;
of(1, 2, 3).subscribe(console.log); // 1, 2, 3
from(["A", "B"]).subscribe(console.log); // A, BfromEvent
const { fromEvent } = rxjs;
const button = document.getElementById("btn");
const click$ = fromEvent(button, "click");
const sub = click$.subscribe(() => console.log("click"));订阅与取消订阅
const { interval } = rxjs;
const sub = interval(1000).subscribe(v => console.log("tick", v));
setTimeout(() => sub.unsubscribe(), 5000);4. 基础操作符
操作符就是转换或过滤 Observable 值的函数。
const { of } = rxjs;
const { map, filter, take } = rxjs.operators;
of(1, 2, 3, 4, 5)
.pipe(
filter(n => n % 2 === 1),
map(n => n * 10),
take(2)
)
.subscribe(console.log); // 10, 30本课程用到的核心操作符分几类:创建(of, from, interval, timer)、转换(map, filter)、组合(merge, concat)、过滤(take, first, debounceTime)。
5. DOM 事件处理
点击计数器
const { fromEvent } = rxjs;
const btn = document.getElementById("btn");
const output = document.getElementById("output");
let count = 0;
fromEvent(btn, "click").subscribe(() => {
count += 1;
output.textContent = `Clicks: ${count}`;
});实时搜索(基础)
const { fromEvent } = rxjs;
const { map, debounceTime } = rxjs.operators;
const input = document.getElementById("search");
fromEvent(input, "input")
.pipe(
map(e => e.target.value.trim()),
debounceTime(300)
)
.subscribe(term => console.log("Search:", term));6. 异步处理
Observable vs Promise
Promise 一般只返回一个未来值。Observable 可以持续发出多个值,而且能 unsubscribe 取消。这是本质区别。
使用 RxJS ajax 调用 API
const { ajax } = rxjs.ajax;
ajax
.getJSON("https://jsonplaceholder.typicode.com/users")
.subscribe({
next: data => console.log("Users:", data),
error: err => console.error("HTTP error:", err),
complete: () => console.log("Completed")
});7. 错误处理与结束
const { of } = rxjs;
const { catchError, retry } = rxjs.operators;
const { ajax } = rxjs.ajax;
ajax
.getJSON("https://api.example.com/data")
.pipe(
retry(2),
catchError(err => {
console.error("Request failed:", err);
return of([]);
})
)
.subscribe({
next: data => console.log(data),
complete: () => console.log("Finished")
});几个关键点:catchError 捕获并处理错误,retry 失败后重试,complete 流正常结束时触发,unsubscribe 手动停掉流。
8. 最佳实践
我的几条经验:无限流(interval、fromEvent)一定记得取消订阅,否则内存泄漏跑不掉。用 pipe 组织操作符,可读性好很多。别把复杂业务逻辑全塞进 subscribe,那会让代码很难维护。调试时 tap 是你的好朋友。
9. 最终项目(建议)
做个实时搜索迷你应用,把整个流程串起来。
步骤:创建输入框,fromEvent 监听输入,map + debounceTime 处理用户输入,ajax.getJSON 请求 API,渲染搜索结果,catchError 处理异常。
这个项目把课程基础知识全串了一遍。
10. 资源与下一步
官方文档:
推荐练习:用 interval 做计时器,做个 + / - 计数器,用公共 API 做实时搜索,练习 retry 的重试逻辑。
接下来可以学中级主题了:switchMap、mergeMap、Subject、进阶流组合。