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

无返回值Promise链式调用最佳实践(Express服务场景)

问题解决及最佳实践建议

1. 空响应的规范写法

你现在用res.send(undefined)的方式不符合HTTP语义,更规范的做法是直接返回 204 No Content 状态码:

res.sendStatus(204)

204是HTTP标准定义的「请求处理成功、无返回内容」的状态码,不会附带任何响应体,完全匹配你当前的业务场景。

2. Promise 逻辑优化

你当前的代码混用async/await和.then,嵌套层级深,容易出现异步漏捕获、逻辑顺序出错的问题,建议全用async/await改写拍平逻辑,可读性和可维护性都更高:

app.post("/pdf", async (req, res) => {
  res.contentType("application/json");
  try {
    if (req.body.layout.callsheet) {
      await toPNG.pdfToPNG(req.body.layout.callsheet, pdfPath);
      await generatePDf(req.body.data, pdfPath, req.body.layout.selected);
      if (layout === "landscape") {
        await call.doubleCover(`${pdfPath}`, `${pdfPath}-coverSheet.png`);
      } else {
        await call.singleCover(`${pdfPath}`, `${pdfPath}-coverSheet.png`);
      }
    } else {
      await generatePDf(req.body.data, callSheet);
    }
    res.sendStatus(204);
  } catch (err) {
    console.error(err);
    res.status(500).send(err.toString());
  }
});

3. Heroku 超时问题解决

Heroku 路由层默认有30秒的超时限制,只要你的请求处理超过30秒,不管你服务端逻辑有没有跑完,Heroku都会主动断开连接返回503错误。如果你处理大数据集的耗时经常超过30秒,同步等处理完再返回的模式是走不通的,建议改成异步任务模式:

  • 接口收到请求后,先把PDF生成任务存入持久化队列(推荐基于Redis的BullMQ,简单场景也可以用内存队列),立刻返回202 Accepted状态码,同时返回任务ID
  • 后端单独跑worker进程消费队列里的任务,处理完后更新任务状态
  • 前端拿到任务ID后定时轮询查询任务状态,处理完成后再给用户提示
    这种模式完全不会触发超时限制,也能更好的应对任务堆积的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 17:54:06