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

Node.js中首次下载Zip文件失败,后续尝试正常的问题排查

问题分析与解决方案

看起来你遇到的这个「首次下载Zip卡住、后续正常」的问题,大概率是异步操作未正确等待导致的,咱们结合你的代码来拆解:

核心问题点

你当前的代码是同步循环调用createfile,然后直接执行res.zip——但如果createfile是涉及文件IO的异步函数(比如写入文件到磁盘),那第一次请求时,res.zip执行的时候,文件其实还没创建完成!这就会导致压缩操作卡住;而后续请求时,之前的文件已经存在了,所以res.zip能正常找到文件完成压缩。

另外提个小细节:你的路由拼写错了(/downlaod_file → /download_file),虽然不影响功能,但建议修正避免后续混淆。

修正后的代码示例

我们需要把路由处理函数改成异步的,等待所有文件创建完成后再调用res.zip:

// 注意加上async关键字
app.post('/download_file', ensureAuthenticated, async (req, res) => {
  try {
    const json_array = [];
    
    // 用for...of循环配合await,确保每个文件都创建完成再继续
    for (const id of req.body.idlist) {
      // 假设createfile返回Promise,如果原函数是回调式的,需要先包装成Promise(见下文)
      await createfile(id);
      
      json_array.push({ 
        path: `file_${id}.docx`, 
        name: `file${id}.docx` 
      });
    }
    
    // 所有文件都准备好后,再执行压缩下载
    res.zip(json_array);
  } catch (error) {
    // 别忘了处理错误,避免请求挂起
    res.status(500).send(`文件生成失败:${error.message}`);
  }
});

如果createfile是回调式函数

如果你的createfile原本是基于回调的(比如createfile(id, callback)),需要先把它包装成Promise:

// 包装成Promise版本的createfile
function createfileAsync(id) {
  return new Promise((resolve, reject) => {
    createfile(id, (err) => {
      if (err) {
        reject(err); // 出错时抛出错误
      } else {
        resolve(); // 成功时标记完成
      }
    });
  });
}

然后在循环里替换成await createfileAsync(id)即可。

额外建议

每次下载后,临时生成的.docx文件会留在磁盘上,建议在res.zip完成后清理这些文件,避免占用存储空间:

res.zip(json_array, (err) => {
  if (!err) {
    // 遍历json_array删除临时文件
    json_array.forEach(item => {
      fs.unlinkSync(item.path);
    });
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:45:26