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

如何基于PDFMake实现异步PDF生成?createPdfKitDocument能否非阻塞?

问题解答

首先明确:printer.createPdfKitDocument本身是同步执行的CPU密集型操作(PDF排版、渲染逻辑均为同步计算),无法直接改成异步API,但可以通过将PDF生成任务隔离到独立线程/进程的方式,避免阻塞主API的事件循环,从而解决并发请求下响应延迟的问题。

具体实现方案

1. 使用Node.js worker_threads 模块(推荐)

把PDF生成的核心逻辑放到Worker线程中,主进程仅负责接收请求、分发任务和接收结果,这样主事件循环不会被CPU密集的PDF生成操作阻塞,多个并发请求可以并行处理。

主进程代码:

const { Worker } = require('worker_threads');

function generatePdf(data) {
  return new Promise((resolve, reject) => {
    const worker = new Worker('./pdf-generator-worker.js', {
      workerData: data
    });
    
    worker.on('message', (result) => {
      if (result.error) reject(new Error(result.error));
      else resolve(result);
    });
    
    worker.on('error', reject);
    
    worker.on('exit', (code) => {
      if (code !== 0) reject(new Error(`PDF生成线程异常退出,代码:${code}`));
    });
  });
}

Worker线程文件(pdf-generator-worker.js):

const { parentPort, workerData } = require('worker_threads');
const PdfPrinter = require('pdfmake');
const fs = require('fs');
const randomstring = require('randomstring');
const FONTS = require('./your-font-config-path'); // 替换为你的字体配置路径
const ReporteCompVenta = require('./your-reporte-class-path'); // 替换为你的报表类路径

try {
  const printer = new PdfPrinter(FONTS);
  const reporte = new ReporteCompVenta(workerData, 'A4');
  const pdfDoc = printer.createPdfKitDocument(reporte.generar(), {});
  
  const fileName = `files/${randomstring.generate(5)}.pdf`;
  
  pdfDoc.pipe(fs.createWriteStream(fileName)
    .on('error', (err) => {
      parentPort.postMessage({ error: err.message });
    })
  );
  
  pdfDoc.on('end', () => {
    parentPort.postMessage({ success: true, fileName });
  });
  
  pdfDoc.end();
} catch (err) {
  parentPort.postMessage({ error: err.message });
}

2. 使用进程池(适合高并发场景)

如果Worker线程的隔离力度不够,或者需要更严格的资源控制,可以用进程池(比如借助poolifier库,或自行实现子进程池),限制同时运行的PDF生成进程数量,避免服务器资源耗尽。

现有代码的优化点

  • 移除测试用的setTimeout,避免无意义的延迟
  • Promise构造函数中的catch块里,应该用reject(err)替代throw(err),否则会导致未捕获的Promise拒绝错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:01:20