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

React中文件下载等待异常求助:大文件未成功加入Zip包

解决Strapi批量下载PDF并生成Zip时未等待文件完成的问题

这个问题的核心是你在map里使用了异步函数,但map本身不会等待这些异步操作完成——它只会立刻返回一组Promise,而你通过判断索引来resolve的逻辑,其实只是确认遍历到了最后一个元素,而非所有文件都已经下载并写入Zip了,大文件因为下载耗时更长,这个问题就更明显。

修复方案:用Promise.all等待所有异步下载完成

把原来的map遍历换成Promise.all,它会等待所有传入的Promise都执行完成后才继续后续逻辑,这样就能确保所有PDF都下载并写入Zip后,再去生成最终的压缩包。

修改后的代码片段如下:

const downloadPdf = async (newData: any) => { 
  return new Promise(async (resolve) => { 
    let PolicyDocData: any; 
    [...some operation...] 
    if (newData.laws) { 
      if (newData.laws.description[0]) { 
        [...some operation to create an array for URL...] 
        let lawDoc = Array.from(new Set(lawDocArray)); 
        
        // 把每个下载任务包装成Promise,存入数组
        const downloadTasks = lawDoc.map(async (val: any) => { 
          const lawUrl = val.url.slice(1); 
          const DocUrl = serverUrl + lawUrl; 
          const response = await fetch(DocUrl, { method: "GET" });
          const blob = await response.blob();
          
          const fileType = ".pdf"; 
          const timeStamp = Math.floor(Date.now() / 1000); 
          const fileName = val.name; 
          let docFileName = fileName + "_" + timeStamp; 
          zip.folder("Compliance/Laws").file(docFileName + fileType, blob); 
        });
        
        // 等待所有下载和写入操作完成
        await Promise.all(downloadTasks);
        // 现在所有文件都已就绪,可以resolve了
        resolve(Contents); 
      } 
    } 
  }).then((Contents: any) => { 
    if (Contents) { 
      Packer.toBlob(PolicyDocumentCreator(Contents)).then((blob) => { 
        zip.generateAsync({ type: "blob" }).then(function (content: any) { 
          saveAs(content, folderName ? folderName : complianceName + ".zip"); 
          setLoading(false); 
        }); 
      }); 
    } 
  }); 
};

为什么原来的方式不行?

  • map遍历异步函数时,会一次性创建所有Promise并开始执行,但不会等待它们完成。你之前判断lawDoc.length - 1 === index时,只是说明循环到了最后一个元素,但这个元素对应的下载任务可能还在进行,前面的任务更不一定完成了。
  • setTimeout是投机取巧的方式,你无法准确预估大文件的下载时间,设置短了还是会有问题,设置长了又会浪费用户时间,完全不符合异步编程的规范。

用Promise.all是最可靠的解决方案,它完美适配这种需要等待多个异步任务全部完成的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:49:39