JavaScript如何将Excel读取函数正确改写为async/await形式
问题根源
你的代码核心问题是没有正确将回调式的FileReader异步逻辑封装为Promise,导致async/await无法等待执行完成:
- 你在
onload事件回调里写的return jsonObj,只是回调函数自身的返回值,不会作为外层Get_DataXls函数的返回结果 - 外层
Get_DataXls在调用readAsBinaryString、注册完onload事件后就直接执行结束,默认返回值是undefined,根本等不到文件读取、Excel解析的流程走完,不管你在函数内哪个位置加await都会出现报错、拿不到结果的问题 - 基于事件/回调的异步API必须手动包装为
Promise实例,才能被async/await正确捕获结果、等待执行完成。
修正后可运行代码
// 点击事件回调也可以直接加async,用await写法替代.then链式调用 document.getElementById('uploadBud').addEventListener('click', async () => { const selectedFile = document.getElementById('importBUDid').files[0]; const arreglo = await Get_DataXls(selectedFile); alert('Ready'); }); async function Get_DataXls(selectedFile) { if (!selectedFile) return null; // 将FileReader逻辑包装为Promise return new Promise((resolve, reject) => { const fileReader = new FileReader(); // 增加错误捕获,避免文件读取异常时出现未捕获错误 fileReader.onerror = () => reject(new Error('Excel文件读取失败')); fileReader.onload = (event) => { const binaryData = event.target.result; const workbook = XLSX.read(binaryData, { type: "binary" }); let parseResult = null; workbook.SheetNames.forEach(sheetName => { // 原写法sheet_to_row_object_array是旧版别名,官方推荐直接用sheet_to_json parseResult = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName]); }); console.log(parseResult); // 读取解析完成后,通过resolve把结果返回给外层 resolve(parseResult); } fileReader.readAsBinaryString(selectedFile); }) }
额外注意事项
- 原代码存在逻辑缺陷:如果Excel包含多个工作表,
forEach遍历过程中parseResult会被后一个工作表的内容覆盖,最终只返回最后一个工作表的解析结果。如果需要获取所有工作表内容,可以把parseResult定义为对象,用工作表名作为key存储每个表的解析结果 - 必须给FileReader增加
onerror异常处理,否则文件损坏、格式不支持等场景会抛出未捕获的全局错误 - 如果要进一步优化读取性能,可以把
readAsBinaryString替换为readAsArrayBuffer,配合XLSX的type: 'array'配置,解析大文件时速度更快、内存占用更低。
内容的提问来源于stack exchange,提问作者madison_sg
相关产品推荐
相关产品推荐

