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

合并两个PDF时触发setTimeout未定义错误,求助解决

合并PDF时抛出ReferenceError: setTimeout is not defined错误

我编写了一个合并两个PDF的函数(运行在forEach循环中,此处省略循环代码)。控制台日志显示PDF已成功加载,但无法生成目标文件"combined.pdf",报错信息:ReferenceError: setTimeout is not defined。

相关代码如下:

// ****** FUNCTION 1 ******
async function loadPDF(pdfBytes) {
  try {
    const loadedPdf = await PDFLib.PDFDocument.load(pdfBytes);
    console.log(`PDF loaded successfully`);
    return loadedPdf;
  } catch (error) {
    console.log(`Error loading PDF:`, error);
    return null;
  }
}

// ****** MAIN FUNCTION ******
async function combinePDFsIntoOne () {

  const cdnjs = 'https://cdn.jsdelivr.net/npm/pdf-lib@1.16.0/dist/pdf-lib.min.js';
  eval(UrlFetchApp.fetch(cdnjs).getContentText());

  const pdfFile1 = pdf;
  const pdfFile2 = pdfP2FileName;

  console.log(typeof pdfFile1) //object
  console.log(pdfFile1)
  /*
  { toString: [Function],
  getName: [Function],
  getBytes: [Function],
  setName: [Function],
  getContentType: [Function],
  setContentType: [Function],
  setBytes: [Function],
  getDataAsString: [Function],
  setDataFromString: [Function],
  isGoogleType: [Function],
  getAllBlobs: [Function],
  setContentTypeFromExtension: [Function],
  copyBlob: [Function],
  getAs: [Function] }
  */

  console.log(typeof pdfFile2) //object
  console.log(pdfFile2)
  /*
  { toString: [Function],
  getName: [Function],
  getBytes: [Function],
  setName: [Function],
  getContentType: [Function],
  setContentType: [Function],
  setBytes: [Function],
  getDataAsString: [Function],
  setDataFromString: [Function],
  isGoogleType: [Function],
  getAllBlobs: [Function],
  setContentTypeFromExtension: [Function],
  copyBlob: [Function],
  getAs: [Function] }
  */

  // Read files as "Binary Strings"
  const pdfBytes1 = new Uint8Array(pdfFile1.getBytes()); 
  const pdfBytes2 = new Uint8Array(pdfFile2.getBytes()); 

  // Create new pdf
  const pdfDoc = await PDFLib.PDFDocument.create();

  // Try loading the first PDF
  const firstPDF = await loadPDF(pdfBytes1); // PDF loaded successfully
  console.log(typeof firstPDF);
  if (!firstPDF) {
    console.log(`Error loading first PDF ${typeof firstPDF}`);
  }
  // Try loading the second PDF
  const secondPDF = await loadPDF(pdfBytes2); // PDF loaded successfully
  if (!secondPDF) {
    console.log(`Error loading second PDF ${typeof secondPDF}`);
  }

  // Get pages to import
  const firstPDFPages = await pdfDoc.copyPages(firstPDF, firstPDF.getPageIndices());
  const secondPDFPages = await pdfDoc.copyPages(secondPDF, secondPDF.getPageIndices());

  // Add pages to the PDF
  firstPDFPages.forEach((page) => pdfDoc.addPage(page));
  secondPDFPages.forEach((page) => pdfDoc.addPage(page));

  const pdfBytes = await pdfDoc.save();
  const newBlob = Utilities.newBlob(Array.from(pdfBytes), 'application/pdf');

  newBlob.setName('combined.pdf');
  holdingFolder.createFile(newBlob);

};

try {
  await combinePDFsIntoOne ();
}
catch(err) {
  console.log(`Error is: ${err}`) // Error is: ReferenceError: setTimeout is not defined
}

问题原因与解决方案

原因

代码运行在Google Apps Script(GAS)环境中,该环境使用Rhino JavaScript引擎,没有原生的setTimeout全局函数。而pdf-lib库的内部异步逻辑依赖了这个函数,因此触发了报错。

解决方法:模拟setTimeout函数

在加载pdf-lib之前,手动模拟setTimeout和clearTimeout函数,让pdf-lib可以正常运行:

// ****** MAIN FUNCTION ******
async function combinePDFsIntoOne () {
  // 为GAS环境模拟setTimeout和clearTimeout
  global.setTimeout = (callback) => {
    // 直接同步执行回调,pdf-lib不需要实际延迟
    callback();
    return 0;
  };
  global.clearTimeout = () => {};

  const cdnjs = 'https://cdn.jsdelivr.net/npm/pdf-lib@1.16.0/dist/pdf-lib.min.js';
  eval(UrlFetchApp.fetch(cdnjs).getContentText());

  // ... 剩余代码保持不变
}

替代方案:使用GAS原生PDF合并能力

如果不想依赖第三方库,可以启用Drive API服务后,使用原生能力合并PDF:

function combinePDFsNative() {
  const fileIds = [pdfFile1.getId(), pdfFile2.getId()];
  const resource = {
    title: 'combined.pdf',
    mimeType: 'application/pdf',
    parents: [{id: holdingFolder.getId()}]
  };
  // 复制第一个PDF作为基础文件
  const combinedFile = Drive.Files.copy(resource, fileIds[0], {
    convert: false,
    ocr: false,
    uploadType: 'multipart'
  });
  
  // 将第二个PDF的页面追加到合并文件中
  Drive.Files.update({}, combinedFile.id, pdfFile2.getBlob(), {
    uploadType: 'media',
    append: true
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:14:56