使用FileReader与Promise读取多文件时数组为空的问题求助
问题:使用FileReader读取多文件内容返回空数组
刚接触异步操作与Promise概念,在使用FileReader时遇到了问题。参考相关讨论后仍无法让脚本正常运行。
我有一个支持多文件选择的文件输入框,希望读取选中文件的内容并存入数组,但最终得到的始终是空数组。以下是我的代码:
const inputElement = document.getElementById("trackfiles"); inputElement.addEventListener("change", (e) => { const selectedFiles = inputElement.files; let p = Promise.resolve(); for (const file of selectedFiles) { p = p.then(() => readAsData(file).then((content) => { files_content.push(content); }), ); } console.log(files_content); }); function readAsData(file) { return new Promise((resolve, reject) => { let reader = new FileReader(); reader.readAsText(file); reader.onload = () => { resolve(reader.result); }; reader.onerror = reject; }); }
选择文件后,控制台输出空数组:
解决方案
你的代码核心问题是异步操作未完成就执行了console.log,同时files_content未提前声明,修复步骤如下:
- 初始化目标数组:在事件回调内声明
files_content,避免未定义问题 - 等待所有异步操作完成后再输出结果:
console.log是同步执行的,此时所有文件读取的异步操作都还没结束,必须在整个Promise链完成后再执行输出
修复后的代码:
const inputElement = document.getElementById("trackfiles"); inputElement.addEventListener("change", (e) => { const selectedFiles = inputElement.files; // 初始化存储内容的数组 const files_content = []; let p = Promise.resolve(); for (const file of selectedFiles) { p = p.then(() => readAsData(file).then((content) => { files_content.push(content); }), ); } // 等待所有文件读取完成后再打印结果 p.then(() => { console.log(files_content); }).catch(err => { console.error('读取文件出错:', err); }); }); function readAsData(file) { return new Promise((resolve, reject) => { let reader = new FileReader(); reader.readAsText(file); reader.onload = () => { resolve(reader.result); }; reader.onerror = reject; }); }
优化方案:并行读取文件
如果不需要按顺序读取文件,用Promise.all可以并行处理所有文件,效率更高:
const inputElement = document.getElementById("trackfiles"); inputElement.addEventListener("change", (e) => { const selectedFiles = inputElement.files; // 将FileList转为数组,生成所有读取任务的Promise const readTasks = Array.from(selectedFiles).map(file => readAsData(file)); Promise.all(readTasks) .then(files_content => { console.log(files_content); }) .catch(err => { console.error('读取文件出错:', err); }); }); function readAsData(file) { return new Promise((resolve, reject) => { let reader = new FileReader(); reader.readAsText(file); reader.onload = () => { resolve(reader.result); }; reader.onerror = reject; }); }
内容的提问来源于stack exchange,提问作者feub
相关产品推荐
相关产品推荐

