2022-05-17 21:30:24
这个问题涉及到 JavaScript 中 FileReader 的异步特性以及变量作用域的理解。以下是详细解答:
核心问题分析异步执行顺序reader.onload 是异步回调函数,它会在 reader.readAsBinaryString() 完成后触发。因此,代码的实际执行顺序是:
同步执行 console.log("nws2=",nws) 和 console.log("tt=",tt)(此时 nws 仍为空数组 [],tt 仍为 "aa")。
异步执行 onload 回调,此时才会修改 nws 和 tt。
变量作用域与闭包
nws 和 tt 在 handleUploadFile 函数作用域内定义,onload 回调通过闭包访问它物扮们,因此回调内对它们的修改会反映到外部。
但由于异步性,外部的 console.log 无法捕获回调内的修改。
为什么 nws1 和 nws2 输出一致?
nws2 在 onload 回调绑定前输出,此时 nws 未被修改。
nws1 在 onload 回调执行后输出,已填充数据。
但你的代码中可能未正确展示 nws1 的输出时机(例如,可能在另一个函数中调用)。实际应为:
nws2:[](同步)
nws1:[填充后的数据罩让灶](异步回调内)
为什么 tt 输出 "aa" 而不是 "bb"?
console.log("tt=", tt) 在 onload 回调绑定前同步执行,此时 tt 未被修改。
若你在 onload 回调外访问 tt,永远得到 "aa";回调内的修改仅在回调内生效。
若需在文件读取完成后操作数滑宏据,必须将逻辑放在 onload 回调内:
handleUploadFile(file, fileList) { let reader = new FileReader(); reader.onload = (e) => { const data = e.target.result; const workBook = xlsx.read(data, { type: "binary" }); const wsname = workBook.SheetNames[0]; const ws = xlsx.utils.sheet_to_json(workBook.Sheets[wsname], { defval: "", range: 1 }); const nws = ws.map(item => ({ patrolPosition: item["x1"], patrolName: item["x2"], patrolCardId: item["x3"], patrolDetail: item["x4"], })); console.log("nws=", nws); // 正确输出数据 this.excelData = nws; // 正确赋值 }; reader.readAsBinaryString(file.raw);}总结通过理解异步执行顺序和作用域,可以避免此类问题。