对读取的Excel文件数据进行拆分并发请求发送到后端服务器

首先,我们先回顾一下文件的读取操作:

本地读取Excel文件并进行数据压缩传递到服务器-CSDN博客

第一步:根据以上博客,我们将原先的handleFile方法,改为以下内容:

复制代码
const handleFile = async(e) => {
    console.time('test')
    const file = e.target.files[0];
    
    const results = await new Promise((resolve,reject) => {
        Papa.parse(file,{
            header:true,
            skipEmptyLines:true,
            complete:resolve, //成功时的回调
            error:reject //失败时的回调
        })
    })

    const data = results.data;
    console.log(data)

};

先对data数据进行打印,获取到一千多行的数据信息

那么如何对1000多条信息进行分组处理呢???

因为我们要对数据进行拆分,所以我们可以将此数据分成200个记录为一组的分组操作。

第二步:对数据进行分组操作

复制代码
const batchSize = 200;
const dataChunks = [];
for(let i=0;i<data.length;i+=batchSize){
    const dataChunks = data.slice(i,i + batchSize);
    dataChunks.push(dataChunks);
}

console.log(data,dataChunks)

第三步:引入eachLimit并对此进行操作

复制代码
import { eachLimit } from "async"; //引入第三方类库  需要安装

以下的handleFile的全部代码

复制代码
    const [results,setResults] = useState([]); //保留解析后的数据
    const [progress,setProgress] = useState({completed:0,total:0});
    
    const handleFile = async(e) => {
        console.time('test')
        const file = e.target.files[0];
        
        const results = await new Promise((resolve,reject) => {
            Papa.parse(file,{
                header:true,
                skipEmptyLines:true,
                complete:resolve, //成功时的回调
                error:reject //失败时的回调
            })
        })
 
        const data = results.data;
        console.log(data)

        const batchSize = 200;
        const dataChunks = [];
        for(let i=0;i<data.length;i+=batchSize){
            const dataChunks = data.slice(i,i + batchSize);
            dataChunks.push(dataChunks);
        }

        console.log(data,dataChunks) //输出原先数据以及分组后的数据

        const processData = async(dataChunks) => {
            const totalChunks = dataChunks.length; //总共需要发送的请求次数
            let completedChunks = 0; //已经完成的请求次数
            const resultsArray = []; //保存所有请求的结果

            const notifyProgress = () => {
                setProgress({
                    completed: completedChunks,
                    total: totalChunks,
                })
            }
            await eachLimit(dataChunks,5,async(chunk) => {
                const gzip = pako.gzip(JSON.stringify(chunk),{to:"string"});
                try{
                    const response = await fetch('http://localhost:3000',{
                        method:"POST",
                        body:gzip,
                        headers:{
                            "Content-Type":"application/octet-stream",
                        }
                    });

                    const result = {
                        index:dataChunks.indexOf(chunk),
                        success:response.ok,
                        status:response.status,
                        message:response.statusText,
                    };

                    resultsArray.push(result);
                    completedChunks++;
                    notifyProgress();
                    setResults([...resultsArray]);
                }catch (error){
                    const result = {
                        index:dataChunks.indexOf(chunk),
                        success:false,
                        status:500,
                        message:error.message,
                    };
                    resultsArray.push(result);
                    completedChunks++;
                    notifyProgress();
                    setResults([...resultsArray]);
                }
            });
            console.timeEnd("test")
        }
        await processData(dataChunks);
    };

<input type="file" onChange={handleFile} accept='.csv' />

进度的展示

复制代码
<h2>进度的展示</h2>
<div>
    Progress: { progress.completed } / { progress.total }
</div>

结果展示

复制代码
<h2>结果显示</h2>
<ul>
    {results && 
        results.map(result => {
            return <li key={result.index}>
                {result.index} - {result.success.toString()} - {result.status} - {""}
                {result.message}
            </li>
        })
    }
</ul>

此时,我们就可以尝试读取一个文件进行测试

由此看出,我们的顺序并不是按照顺序来排列的,那是因为我们进行请求的并发处理并不代表一定是按照顺序去进行数据的返回,因为可能在请求中,因为网络的问题先请求的操作可能会成为后返回的操作。

而result也是按照一定的批次进行返回的,而不是一条一条返回。

此时,我们点击修改背景颜色的按钮,也会很卡顿,所以这种情况需要在后续进行性能优化。

那么以上就是这些内容,希望对您有所帮助。

相关推荐
用户47949283569158 分钟前
记住这张时间线图,你再也不会乱用 useEffect / useLayoutEffect
前端·react.js
九河云18 分钟前
华为云 ECS 弹性伸缩技术:应对业务峰值的算力动态调度策略
大数据·服务器·人工智能·物联网·华为云
咬人喵喵21 分钟前
14 类圣诞核心 SVG 交互方案拆解(附案例 + 资源)
开发语言·前端·javascript
问君能有几多愁~34 分钟前
C++ 日志实现
java·前端·c++
咬人喵喵35 分钟前
CSS 盒子模型:万物皆是盒子
前端·css
2401_8603195241 分钟前
DevUI组件库实战:从入门到企业级应用的深度探索,如何快速应用各种组件
前端·前端框架
云宏信息1 小时前
运维效率提升实战:如何用轻量化云管平台统一纳管与自动化日常资源操作
运维·服务器·网络·架构·云计算
韩曙亮1 小时前
【Web APIs】元素滚动 scroll 系列属性 ② ( 右侧固定侧边栏 )
前端·javascript·bom·window·web apis·pageyoffset
珑墨1 小时前
【浏览器】页面加载原理详解
前端·javascript·c++·node.js·edge浏览器
FreeBuf_1 小时前
Next.js 发布扫描工具:检测并修复受 React2Shell 漏洞(CVE-2025-66478)影响的应用
开发语言·javascript·ecmascript