react中防止数据多大并需要二次加工处理进行单线程转多线程webworker优化处理(不借助react-webworker)
需求背景
在开发中 有的需求往往和分页等会产生冲突 比如批量修改后又进行自定义修改 后端无法获取前置更改等 这个时候不分页数据量会很大而且需要我们对数据进行二次加工 然后需要我们进行优化处理 这就可以采取webworker多线程处理了 下面是一个没有借助react-webworker插件的原生简单例子
实现过程
即粘即用 逻辑步骤我都写在代码注释里面了
这是我的目录结构 worker.js为我创建的多线程处理文件 选中的为我使用的文件地址
worker.js页面
// 定义worker线程脚本代码
const workercode = () => {
self.onmessage = function (e) {
//e为通信传入的对象
//这里写需要对数据处理加工的内容
//例子
const result=[]
result=e.data.map(item=>item.name)
//发送回去
self.postMessage(result);
};
};
//为了将workerCode函数转化为一个可由Worker构造函数使用的URL,将该函数转换为字符串,并从中提取函数体。接着,使用此函数体内容创建一个Blob对象,并通过URL.createObjectURL创建一个指向该Blob的URL。 把脚本代码转为string
let code = workercode.toString();
code = code.substring(code.indexOf('{') + 1, code.lastIndexOf('}'));
const blob = new Blob([code], { type: 'application/javascript' });
const worker_script = URL.createObjectURL(blob);
module.exports = worker_script;
使用页面
//1.引入
import worker_script from './worker.js';
//2.定义
const worker = new Worker(worker_script);
//3.发送数据及接收 我这边直接放入一个例子 核心内容会标注
const applyData = useCallback(
async (num, urlFilterLevelLists, wall) => {
//开启loading
setSpinLoading(true);
try {
// 获取原始数据
const res = await getApplyList(cpeId);
// 将数据发送到 Web Worker 处理
worker.postMessage({
data: res,
wall,
urlFilterLevelLists,
num,
level,
});
// 监听 Web Worker 的返回结果
worker.onmessage = (e) => {
const { processedData, idMap } = e.data;
batchUpdates(() => {
setExpandedRowKeys(Array.from(idMap.values()));
setApplyDataSource(processedData);
});
};
} finally {
//结束loading
setSpinLoading(false);
}
},
[cpeId],
);
注:期间在worker.js中写逻辑时 定义函数等因为闭包需要写到onmessage内 里面foreach/for in写法可能会导致报错 写成for即可 若遇到报错promise未定义等 大概率是通信没有成功