调用reader.readAsArrayBuffer后返回的数组为空是什么原因?
问题根本原因
FileReader的readAsArrayBuffer是异步操作,调用后不会立刻执行onload内的逻辑,JS主线程会先继续向下执行,直接返回了还没被赋值的uploadData空数组。- 控制台能打印出内容是因为控制台对引用类型的打印是延时求值的,你点开查看内容时异步回调已经执行完并把数据推入了数组,实际赋值给
hello变量时数组仍为空。
修复方案
把validateSpreadsheet改造为返回Promise的异步函数,等待所有文件处理完成后再返回结果:
// 调用时需要放在async函数内,用await获取结果 const hello = await validateSpreadsheet(file, rows) async function validateSpreadsheet(fileUpload, templateRows) { let uploadData = []; const fileProcessTasks = []; for (const file of fileUpload.files) { const fileExtension = file.name.split(".").pop(); let valid = false; if (fileExtension === "csv") { valid = true; } if (!valid) { throw "Unsupported file type, file must be of type .csv"; } // 单个文件处理逻辑封装为Promise const singleFileTask = new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { try { const data = new Uint8Array(e.target.result); const workbook = XLSX.read(data, { type: "array", cellDates: true, dateNF: "dd/mm/yyyy", }); if (workbook.SheetNames.length === 0) { console.error("No sheets"); return resolve(); } for (const sheetName of workbook.SheetNames) { const rows = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { defval: null, }); uploadData.push(...rows); } resolve(); } catch (err) { reject(err); } }; reader.onerror = () => reject(reader.error); reader.readAsArrayBuffer(file); }) fileProcessTasks.push(singleFileTask); } // 等待所有文件处理完成再返回结果 await Promise.all(fileProcessTasks); return uploadData; }
调用注意事项
如果外层不方便用async,也可以用then方法接收结果:
validateSpreadsheet(file, rows).then(hello => { // 此处可处理拿到的hello数据 })
内容的提问来源于stack exchange,提问作者user16603330
相关产品推荐
相关产品推荐

