JavaScript实现文件处理循环中等待loadFileIntoMemory函数执行完成后再进入下一次迭代
解决文件串行处理的问题
看起来你需要让文件处理操作串行执行——也就是等前一个文件的加载、脱敏、下载全流程完成后,再开始处理下一个文件。问题出在loadFileIntoMemory是异步操作(依赖FileReader的回调逻辑),而原来的for循环会直接连续调用它,根本不会等待异步操作完成。
下面是具体的改造方案:
步骤1:将loadFileIntoMemory包装为返回Promise的函数
我们需要把基于回调的异步逻辑转换成Promise,这样就能用await来等待整个流程结束。
步骤2:把processFiles改为async函数,用await实现串行执行
借助async/await配合for...of循环,确保每次只有一个文件在处理,前一个完成后才会启动下一个。
修改后的完整代码
// 改造loadFileIntoMemory,返回Promise function loadFileIntoMemory(file) { return new Promise((resolve, reject) => { originalValues[file.name] = {}; const filename = file.name; const reader = new FileReader(); reader.onload = function () { try { const arrayBuffer = reader.result; const byteArray = new Uint8Array(arrayBuffer); dataSet = dicomParser.parseDicom(byteArray); storeOriginalValues(filename); console.log("De-identifying values"); for (const [key, value] of Object.entries(elementsToRemove)) { const element = dataSet.elements[value]; if (typeof element !== "undefined") { for (let i = 0; i < element.length; i++) { dataSet.byteArray[element.dataOffset + i] = 32; } } } replaceOccurences(filename, originalValues[filename].PatientID); console.log('Downloading File'); const blob = new Blob([dataSet.byteArray], { type: "application/dicom" }); const url = window.URL.createObjectURL(blob); window.open(url); window.URL.revokeObjectURL(url); // 当前文件处理完成,标记Promise成功 resolve(); } catch (error) { // 处理过程中出错,标记Promise失败 reject(error); } }; // 捕获文件读取失败的情况 reader.onerror = function () { reject(new Error(`Failed to read file: ${file.name}`)); }; reader.readAsArrayBuffer(file); }); } // 改造processFiles为async函数,实现串行处理 async function processFiles(files) { for (const file of files) { console.log(`Loading File into memory: ${file.name}`); try { // 等待当前文件的所有操作完成后,再进入下一次循环 await loadFileIntoMemory(file); console.log(`Finished processing: ${file.name}`); } catch (error) { console.error(`Error processing file ${file.name}:`, error); // 可选:这里可以选择终止整个流程(throw error),或者继续处理下一个文件(continue) } } }
关键细节说明
- Promise包装:把
FileReader的异步逻辑封装进Promise,成功时调用resolve(),失败时调用reject(),让我们能通过await等待整个文件处理流程结束。 - async/await配合循环:
processFiles标记为async后,在for...of循环里用await调用loadFileIntoMemory,循环会自动暂停,直到当前Promise完成,才会处理下一个文件。 - 错误处理:加入
try/catch捕获单个文件的处理错误,你可以根据业务需求选择终止整个流程,或者跳过错误文件继续处理后续文件。
这样改造后,就完全实现了你要的“处理完一个文件再处理下一个”的需求啦。
内容的提问来源于stack exchange,提问作者asdadad
相关产品推荐
相关产品推荐

