响应式编程是一种面向数据流和变更传播的异步编程范式。RxJS是一个使用可观察对象进行响应式编程的库,它让组合异步代码和基于回调的代码变得更简单,下面展示业务功能在rxjs中是怎么实现的
竟态问题
比如查询按钮,点击查询时要是上一次查询没有结束直接取消,只请求当前查询
import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
const queryBtnEle = document.getElementById('query-btn') as HTMLInputElement;
fromEvent(queryBtnEle, 'click')
.pipe(switchMap(target => ajax('https://api.github.com/users?per_page=5')))
.subscribe(data => {
console.log('请求数据', data);
});
与之相对的
exhaustMap操作符表示前一个没有结束,当前的取消
输入提示建议
可观察对象可以简化输入提示建议的实现方式。典型的输入提示要完成一系列独立的任务:
- 移除输入值前后的空白字符,并确认它达到了最小长度
- 防抖(这样才能防止连续按键时每次按键都发起 API 请求,而应该等到按键出现停顿时才发起)
- 如果输入值没有变化,则不要发起请求(比如按某个字符,然后快速按退格)
- 如果已发出的 AJAX 请求的结果会因为后续的修改而变得无效,那就取消它
import { fromEvent } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
const searchBox = document.getElementById('search-box') as HTMLInputElement;
const typeahead = fromEvent(searchBox, 'input').pipe(
map(e => (e.target as HTMLInputElement).value),
filter(text => text.length > 2), // 过滤数据
debounceTime(10), // 防抖
distinctUntilChanged(), // 数据值没变不发送数据
switchMap(searchTerm => ajax(`/api/endpoint?search=${searchTerm}`)) // 已发数据没来就取消
).subscribe(data => {
console.log('查询提示数据', data)
)
合并数据
多个AJAX请求都完成才返回合并后的数据
import { forkJoin } from 'rxjs';
import { ajax } from 'rxjs/ajax';
forkJoin([ajax(`/api1`), ajax(`/api2`), ajax(`/api3`)]).subscribe(result => {
const [res1, res2, res3] = result;
});
combineLatest,zip是相关合并数据场景
防抖和节流
节流如下
import { throttleTime } from 'rxjs/operators';
const scrollEle = document.getElementById('scroll-content');
const typeahead = fromEvent(scrollEle, 'scroll').pipe(throttleTime(100));
typeahead.subscribe(event => {
// 滚动时每100毫秒取一个数据
console.log('滚动事件对象', event);
});
防抖在输入场景中使用 如上面的'输入提示建议'
缓冲
游戏技能组合键
import { bufferTime, filter } from 'rxjs/operators';
fromEvent(document, 'keypress')
.pipe(
bufferTime(100), // 100毫秒内的按键数据变成数组向下传
filter((res: KeyboardEvent[]) => {
if (res.length >= 3) {
return res.every(val => 'abc'.indexOf(val.key) !== -1);
}
return false;
})
)
.subscribe(() => {
console.log('放abc组合按键技能');
});
还有如: 群聊天设置消息缓冲,太多人聊天每条数据一来马上渲染,消息一下来太多很可能变卡,对消息缓冲一个时间段来的消息一起渲染,有效提高用户体验