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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 20:57:33