抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

RxJS 是一个库,用于使用可观察序列编写异步和基于事件的程序‎,RxJS 极大地减少处理事件控制逻辑,让代码更简洁。

需求

需求是这样的:

页面上有输入框,输入数量计算价格,数量和价格的关系有一张表,匹配输入数量最高档位,有剩余应当继续匹配,对非法输入拦截.

CPT2203220614-1260x640

买 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 再打个组。。

CPT2203220649-607x104

评论