大数据量计算时的延迟统一处理

最近项目开发中遇到类似如下图所示的功能。上半部分是树形选择器,能够通过上面的"全选"切换树形选项的全选和取消全选。下半部分是表格,需要根据树形选择器勾选的数据实时生成表格数据。每个项目下都包含用户列表选项数据,可以单条设置每个项目的用户,也可以批量设置所有项目的用户。而批量设置用户的选项需要实时根据表格数据的变化动态计算。

当树形选择器单条数据勾选,或者全选的选项非常少时,造成的表格数据变化以及后续的批量用户选项计算的工作量很小。但是如果全选操作的数据达到几十条、上百条时,每条被勾选的树形选项都会触发一次树形选择器的check-change事件,其中都会对应变化表格的数据以及批量设置用户选项的重新计算。

但对于全选批量处理的情况,我们没有必要对于每一次树形选项的勾选造成的表格数据变化都重新计算批量设置用户的选项。我们可以等所有选项变化对应的表格数据的变化都更新完成,再一次性的统一计算批量设置用户的选项。

功能实现

在"全选"change事件的事件处理函数handleCheckAllChange中,首先将"批量处理数据"标识isBatchUpdating设置为true,然后通过树形选择器的setCheckedKeys方法勾选或者取消勾选所有的树形选项。

js 复制代码
// 处理全选变化
function handleCheckAllChange(isChecked) {
  // 设置批量处理数据标识
  isBatchUpdating = true;

  if (isChecked) {
    const allKeys = treeData.value.map((item) => item.id);
    treeRef.value.setCheckedKeys(allKeys);
  } else {
    treeRef.value.setCheckedKeys([]);
  }
}

每个树形选项的状态变化都会触发一次树形选择器的check-change事件。在该事件的处理函数中首选会根据isBatchUpdating标识进行判断,如果当前在批量处理数据状态,则先将数据统一缓存在batchData数组中;否则对单条树形选项的勾选去对应生成新的表格数据或者删除已有的表格数据。

js 复制代码
// 处理树形选择变化
function handleTreeCheckChange(node, isChecked) {
  // 当通过全选批量处理数据值,先将数据缓存,整体更新完表格数据后,再一次计算批量设置用户选项
  if (isBatchUpdating) {
    batchData.push(node);
    batchData.isChecked = isChecked;
    return;
  }

  if (isChecked) {
    addTableData(node);
  } else {
    delTableData(node);
  }
  // 更新全选checkbox状态
  updateCheckAll();
}

表格数据的变化会通过watch监听去更新"批量设置用户"选项的重新计算,此外也可以通过计算属性computed来生成"批量设置用户"选项。

js 复制代码
// 监听表格变化,实时计算能够批量设置的用户选项
let watchHandle = watch(
  tableData,
  () => {
    updateBatchUserOpts();
  },
  {
    immediate: true,
    deep: true,
  }
);

当批量处理数据batchData生成结束,我们就可以继续去统一处理表格数据的更新以及"批量设置用户"选项的生成。

这部分功能需要在上面的"全选"逻辑之后进行,但是在执行setCheckedKeys勾选树形选项后,会触发树形选项的check-change。我们需要在所有的树形选项的check-change同步逻辑结束之后再在"全选"的事件回调函数handleCheckAllChange中进行后续的逻辑。

此时我们需要借助"事件循环"中的概念,使用"微循环"使得后续逻辑能够在所有的同步任务执行完成之后进行,可以通过Promise.then来实现。

此外在统一进行表格数据处理前,需要停止对表格数据的watch监听,等表格更新完成再恢复对表格数据的监听。

js 复制代码
// 处理全选变化
function handleCheckAllChange(isChecked) {
  // 设置批量处理数据标识
  isBatchUpdating = true;

  if (isChecked) {
    const allKeys = treeData.value.map((item) => item.id);
    treeRef.value.setCheckedKeys(allKeys);
  } else {
    treeRef.value.setCheckedKeys([]);
  }

  // 微循环后延迟处理
  Promise.resolve().then(() => {
    // 取消表格数据监听
    watchHandle.pause();

    // 批量更新表格数据
    for (const node of batchData) {
      if (batchData.isChecked) {
        addTableData(node);
      } else {
        delTableData(node);
      }
    }
    // 更新批量设置用户选项
    updateBatchUserOpts();
    // 恢复表格数据监听
    watchHandle.resume();
    // 重置批量处理数据标识和缓存
    isBatchUpdating = false;
    delete batchData.isChecked;
    batchData = [];
  });
}

总结:

当需要批量处理数据导致大数据量计算时会非常影响性能,此时可以先将数据缓存起来,然后通过Promise.then"微循环"延迟统一处理数据,能够提升处理性能。

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端