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

FileReader分段读文件时async/await失效,segments为空问题排查

问题分析与解决方案

核心问题

你这段代码的错误在于误用了await:reader.readAsArrayBuffer()是基于事件回调的异步API,它不返回Promise,所以await根本不会等待load事件触发完成。循环会快速执行完所有分段的读取请求,但每个分段的加密和segments.push()操作是在load回调里异步执行的——当你后续处理segments时,这些回调还没来得及执行,数组自然是空的;而alert弹窗给了浏览器足够时间完成所有异步回调,所以此时数组能正常显示内容。

修正后的代码

把FileReader的逻辑包装成Promise,确保每次循环都等待当前分段的读取、加密完成后再进入下一次循环:

while (j < size) {
    const blob = selectedFiles[i].slice(offset, offset + chunk_size);
    // 将FileReader的读取逻辑包装为Promise
    const result = await new Promise<ArrayBuffer>((resolve, reject) => {
        const reader = new FileReader();
        reader.addEventListener('load', () => resolve(reader.result as ArrayBuffer));
        reader.addEventListener('error', reject);
        reader.readAsArrayBuffer(blob);
    });
    // 执行加密并添加到数组
    const wordArray = CryptoES.lib.WordArray.create(result);
    const segment = CryptoES.AES.encrypt(wordArray, pass).toString();
    segments.push(segment);

    offset += chunk_size;
    j += chunk_size;
}

代码优化建议

  1. 用Blob.arrayBuffer()替代FileReader
    现代浏览器原生支持Blob的arrayBuffer()方法,它直接返回Promise,无需手动包装,代码更简洁易维护:

    while (j < size) {
        const blob = selectedFiles[i].slice(offset, offset + chunk_size);
        const buffer = await blob.arrayBuffer();
        const wordArray = CryptoES.lib.WordArray.create(buffer);
        const segment = CryptoES.AES.encrypt(wordArray, pass).toString();
        segments.push(segment);
    
        offset += chunk_size;
        j += chunk_size;
    }
    
  2. 复用FileReader(兼容旧浏览器)
    如果必须兼容不支持Blob.arrayBuffer()的旧浏览器,可以复用单个FileReader实例,减少内存开销:

    const reader = new FileReader();
    const readBlob = (blob: Blob): Promise<ArrayBuffer> => {
        return new Promise((resolve, reject) => {
            reader.onload = () => resolve(reader.result as ArrayBuffer);
            reader.onerror = reject;
            reader.readAsArrayBuffer(blob);
        });
    };
    
    while (j < size) {
        const blob = selectedFiles[i].slice(offset, offset + chunk_size);
        const buffer = await readBlob(blob);
        const wordArray = CryptoES.lib.WordArray.create(buffer);
        const segment = CryptoES.AES.encrypt(wordArray, pass).toString();
        segments.push(segment);
    
        offset += chunk_size;
        j += chunk_size;
    }
    
  3. TypeScript类型优化
    给变量添加明确的类型声明,比如将segments定义为string[],避免隐式类型带来的潜在问题。

内容的提问来源于stack exchange,提问作者Julius Babies

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 10:39:16