You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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;
  });
}

选择文件后,控制台输出空数组:
Chrome dev tools log


解决方案

你的代码核心问题是异步操作未完成就执行了console.log,同时files_content未提前声明,修复步骤如下:

  1. 初始化目标数组:在事件回调内声明files_content,避免未定义问题
  2. 等待所有异步操作完成后再输出结果: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 20:37:10