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

Async函数FileReader问题:数组打印正常但length属性为0

问题根因

出现这个现象是两个逻辑问题共同导致的:

  • FileReader.readAsText()本身是事件驱动的异步API,不返回Promise,你在代码里写的await reader.readAsText(blob)没有任何等待效果,外层await parseFile()执行到return的时候,文件分块读取流程根本没执行完,此时ansList还是空数组,所以打印ansList.length得到0。
  • 控制台打印引用类型值时是懒加载的:你看到打印出来的数组展开后有内容,是因为你手动在控制台展开数组的时候,异步读取流程已经跑完、哈希值已经被push进数组了,不是console.log执行的那一刻数组里就有值。
修复方法

把整个分块读取逻辑用Promise包装,只有当所有分块读取完成、哈希计算结束后才把结果resolve出去,保证await能等到真实的返回值:

async function parseFile(file, type) {
  const fileSize = file.size;
  const chunkSize = 1024 * 1024; // 单块大小1MB
  let offset = 0;
  const hash = sha1.create();
  const ansList = [];

  return new Promise((resolve, reject) => {
    const readEventHandler = async function (evt) {
      if (evt.target.error) {
        console.log('Read error: ' + evt.target.error);
        reject(evt.target.error);
        return;
      }
      offset += evt.target.result.length;
      await hash.update(evt.target.result);

      if (offset >= fileSize) {
        const ans = await hash.hex();
        console.log(ans);
        ansList.push(ans);
        if (type.localeCompare('multiple') === 0) {
          filesUploadHashes.PostFiles.push(ans);
        } else {
          filesUploadHashes.Thumbnail.push(ans);
        }
        resolve(ansList);
        return;
      }
      chunkReaderBlock(offset, chunkSize, file);
    };

    const chunkReaderBlock = function (_offset, length, _file) {
      const reader = new FileReader();
      const blob = _file.slice(_offset, length + _offset);
      reader.onload = readEventHandler;
      reader.onerror = err => reject(err);
      reader.readAsText(blob);
    };

    // 启动第一块读取
    chunkReaderBlock(offset, chunkSize, file);
  });
}

补充提示:如果要计算非文本文件(图片、视频、压缩包等)的哈希,不要用readAsText(),会因为文本编码转义导致哈希值计算错误,替换成readAsArrayBuffer()即可。

内容的提问来源于stack exchange,提问作者Sukhamjot Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:54:20