RxJS 是一个库,用于使用可观察序列编写异步和基于事件的程序,RxJS 极大地减少处理事件控制逻辑,让代码更简洁。
需求
需求是这样的:
页面上有输入框,输入数量计算价格,数量和价格的关系有一张表,匹配输入数量最高档位,有剩余应当继续匹配,对非法输入拦截.
买 6 个用户 = 5 档 950元 + 1 人 200 元 = 950 + 200 = 1150 元
实现
思路分析:用 rxjs 的 fromEvent
订阅原生 dom 事件,使用 pipe 处理输入流,配合 rxjs 的 operator(操作符) 对事件流操作。
代码:
// 购买员工计算参考价格
function registerMoneyComputed() {
// 导入 rxjs
const { fromEvent, operators } = rxjs;
// input 输入框
const moneyInputElem = document.querySelector("#money-input");
// 价格计算函数
const computeMoney = (value) => {
// 价格表
const priceMap = {
1: 200,5: 950,20: 3600,50: 8000,100: 15000,200: 29000,500: 55000,
};
// 提取 key 之后反置数组,从后往前匹配
const priceArray = Object.keys(priceMap).reverse();
let rest = 0,
money = 0;
for (const grade of priceArray) {
rest = value - grade;
while (rest >= 0) {
// 如果有剩余,应当继续迭代本次剩余
// 并将金额累加
money += priceMap[grade] || 0;
value -= grade;
rest = value - grade;
}
}
return money;
};
// 将价格渲染到页面
const render = (value) => {
const moneyElem = document.querySelector("#money");
moneyElem.innerHTML = value;
};
const input$ = fromEvent(moneyInputElem, "input");
input$
.pipe(
// 节流、提取 value、转成 number
operators.debounceTime(200),
operators.map((elem) => elem.target.value),
operators.map(Number),
// 过滤非法输入
operators.skipWhile(isNaN),
operators.skipWhile((num) => 0 > num || num >= 99999),
// 计算价格
operators.map((value) => computeMoney(value))
)
// 订阅 money 计算结果,更新到 dom
.subscribe((money) => render(money));
}
window.onload = () => {
registerMoneyComputed();
};
照着网上教程瞎写了一点,初来乍到,不太懂 rxjs 的规范,或许应该对 operator 再打个组。。