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

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

当树形选择器单条数据勾选,或者全选的选项非常少时,造成的表格数据变化以及后续的批量用户选项计算的工作量很小。但是如果全选操作的数据达到几十条、上百条时,每条被勾选的树形选项都会触发一次树形选择器的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"微循环"延迟统一处理数据,能够提升处理性能。

相关推荐
Anarkh_Lee2 分钟前
别再手写 conf 了!NgxFlow:基于 React Flow 的 Nginx 可视化与调试神器
前端·nginx·数据可视化
程序员Agions3 分钟前
程序员邪修手册:那些不能写进文档的骚操作
前端·后端·代码规范
jqq6667 分钟前
解析ElementPlus打包源码(五、copyFiles)
前端·javascript·vue.js
Awu122712 分钟前
⚡IndexedDB:现代Web应用的高性能本地数据库解决方案
前端·indexeddb
似水流年_zyh12 分钟前
canvas写一个选择音频区域的组件
前端·canvas
wordbaby38 分钟前
TanStack Router 实战:如何优雅地实现后台管理系统的“多页签” (TabList) 功能
前端·react.js
凌览1 小时前
2026年1月编程语言排行榜|C#拿下年度语言,Python稳居第一
前端·后端·程序员
user86158185781541 小时前
Element UI 表格 show-overflow-tooltip 长文本导致闪烁的根本原因与解法
前端
不会写前端的小丁1 小时前
前端首屏渲染性能优化小技巧
前端
还不秃顶的计科生1 小时前
defaultdict讲解
开发语言·javascript·ecmascript