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; }
代码优化建议
用
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; }复用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; }TypeScript类型优化
给变量添加明确的类型声明,比如将segments定义为string[],避免隐式类型带来的潜在问题。
内容的提问来源于stack exchange,提问作者Julius Babies
相关产品推荐
相关产品推荐

