Node.js Express后端同步处理前端上传PDF的异步问题求助
Hey there! No need to apologize for your English—let's work through this async issue together. The core problem here is that your forEach loop doesn't wait for the pdfParser's asynchronous data-ready events to finish, so your function returns an empty array before any PDF processing is done. Here's how to fix it:
The Root Cause
fs.readdirSync().forEach() runs synchronously, but pdfParser.loadPDF() and its pdfParser_dataReady event are asynchronous. When you loop through files with forEach, you're just kicking off each PDF parse task and moving on immediately—your function doesn't wait for those tasks to complete before returning arrayObjs.
The Solution: Wrap PDF Processing in Promises + Use Promise.all()
We can convert each PDF parse operation into a Promise, then use Promise.all() to wait for all of them to finish before returning the results. Here's your modified getInformationsPdf() function:
async function getInformationsPdf() { const files = fs.readdirSync(folderTemp); // Wrap each file's PDF processing in a Promise const processingPromises = files.map(file => { return new Promise((resolve, reject) => { const pdfParser = new PDFParser(this, 1); const fileLocation = `${folderTemp}${file}`; pdfParser.loadPDF(fileLocation); // Handle errors by rejecting the Promise pdfParser.on("pdfParser_dataError", (errData) => { console.error(errData.parserError); reject(errData.parserError); }); // Resolve the Promise once data is ready pdfParser.on("pdfParser_dataReady", (pdfData) => { const t1 = pdfData.formImage.Pages[0].Texts[32].R[0].T.replace(/%20/g, " "); const t2 = pdfData.formImage.Pages[0].Texts[33].R[0].T.replace(/%20/g, " "); const t3 = pdfData.formImage.Pages[0].Texts[34].R[0].T.replace(/%20/g, " "); const t4 = pdfData.formImage.Pages[0].Texts[35].R[0].T.replace(/%20/g, " "); const t5 = pdfData.formImage.Pages[0].Texts[36].R[0].T.replace(/%20/g, " "); const t6 = pdfData.formImage.Pages[0].Texts[37].R[0].T.replace(/%20/g, " "); const t7 = pdfData.formImage.Pages[0].Texts[38].R[0].T.replace(/%20/g, " "); const t8 = pdfData.formImage.Pages[0].Texts[39].R[0].T.replace(/%20/g, " "); const t9 = pdfData.formImage.Pages[0].Texts[40].R[0].T.replace(/%20/g, " "); const textsPdf = [t1, t2, t3, t4, t5, t6, t7, t8, t9]; const fileWithTexts = { file: fileLocation, texts: textsPdf }; renameFileMatch(fileWithTexts); resolve(fileWithTexts); // Send the processed data back }); }); }); // Wait for ALL PDF processing promises to resolve const arrayObjs = await Promise.all(processingPromises); return arrayObjs; }
How This Works
- Promisify Each Parse: We wrap each
pdfParseroperation in a Promise. The Promise resolves only when thepdfParser_dataReadyevent fires, and rejects if there's an error. - Wait for All Tasks:
Promise.all()takes an array of promises and waits until every single one has resolved (or any rejects). This ensures your function doesn't return until all PDFs are processed. - Keep Your Existing Flow: Since your
getPdf()function already usesawait getInformationsPdf(), this modified version will properly pause execution until all processing is done—so your backend won't send a response before the work is finished.
Just replace your original getInformationsPdf() with this version, and your async issue should be fixed!
内容的提问来源于stack exchange,提问作者Leonardo Petta do Nascimento

