如何在节点上同步处理从前端API接收的文件

问题描述

起初,我为我的英语糟糕而感到抱歉:D

您好,以下情况让我很感兴趣,我在react中创建了一个前端,并在节点中创建了一个通过Express接收请求的后端。 这个想法是,从前端我使用POST方法发送一个pdf文件,后端对该文件进行必要的处理(将页面分成更多文件并在pdf中获取数据),最后它返回这些已处理的pdf 。我想在POST响应中返回这些新文件,但是我遇到了异步问题。 处理文件时,我使用pfd2Json库,该库显然处理异步选择的pdf,并让执行流程继续进行,我的问题是,当我发送该库以处理pdf时,它将放入“后台” “并且执行继续,这导致流程结束,并在库处理pdf之前发送帖子的响应。

发布请求到达时,程序将执行此功能 getPDF()

async function getPdf(fileLocation) {
    let pdf = fileLocation;

    await pdfSeparator(pdf,folderTemp);

    await getinformationsPdf();
    return arrayObj
}

当它执行 getinformationsPdf()时,程序将执行所有操作,但不等待库处理pdf。 在这种情况下,我将每个单独的文件加载到forEach中,使用 pdfParser.loadPDF(fileLocation); 上传我的pdf,他正在等待 pdfParser.on读取所有内容(“ pdfParser_dataReady“,pdfData => {}),仅是因为此方法是异步的,所以它只是调用并将其放在后台,从而使流程继续进行到块的末尾并转到下一个forEach项,而pdf尚未处理。 最后,所有forEach都已执行,并且尚未处理pdf,程序将发送响应,并且来自pdf的数据在后端。 我是否可以在发送响应之前强制等待治疗?

async function getinformationsPdf() {
    let arrayObjs = []
    fs.readdirsync(folderTemp).forEach(file => {
        var pdfParser = new PDFParser(this,1);
        let fileLocation = folderTemp + file;
        pdfParser.loadPDF(fileLocation);
        
        pdfParser.on("pdfParser_dataError",(errData) => {
            console.error(errData.parserError)
        });

        pdfParser.on("pdfParser_dataReady",(pdfData) => {
            let t1 = pdfData.formImage.Pages[0].Texts[32].R[0].T.replace(/%20/g," ");
            let t2 = pdfData.formImage.Pages[0].Texts[33].R[0].T.replace(/%20/g," ");
            let t3 = pdfData.formImage.Pages[0].Texts[34].R[0].T.replace(/%20/g," ");
            let t4 = pdfData.formImage.Pages[0].Texts[35].R[0].T.replace(/%20/g," ");
            let t5 = pdfData.formImage.Pages[0].Texts[36].R[0].T.replace(/%20/g," ");
            let t6 = pdfData.formImage.Pages[0].Texts[37].R[0].T.replace(/%20/g," ");
            let t7 = pdfData.formImage.Pages[0].Texts[38].R[0].T.replace(/%20/g," ");
            let t8 = pdfData.formImage.Pages[0].Texts[39].R[0].T.replace(/%20/g," ");
            let t9 = pdfData.formImage.Pages[0].Texts[40].R[0].T.replace(/%20/g," ");
            let textsPdf = [t1,t2,t3,t4,t5,t6,t7,t8,t9];
            let fileWithTexts = {
                file: fileLocation,texts: textsPdf
            }

            renameFileMatch(fileWithTexts);
            arrayObjs.push(fileWithTexts);
        });
    })
    return arrayObjs;
}

解决方法

如果我对问题的理解正确,getInformationsPdf()将对该文件夹中的每个文件进行循环,并且它不等待pdfParser.on("pdfParser_dataReady"内的处理结束再继续,所以在这段代码中:

    let pdf = fileLocation;

    await pdfSeparator(pdf,folderTemp);

    await getInformationsPdf();
    return arrayObj

它在PDF实际完成处理之前运行return arrayObj,对吗?

因此,我认为您应该使用的模式是使用fs.readdirSync(folderTemp).map来创建一个Promises数组,然后在pdfParser.on("pdfParser_dataReady"的末尾使promise分解。然后,您可以await Promise.all()兑现所有诺言

看起来可能像这样:

async function getInformationsPdf() {
    let arrayObjs = []
    const promises = fs.readdirSync(folderTemp).map(file => {
        return new Promise((resolve,reject) => {
            var pdfParser = new PDFParser(this,1);
            let fileLocation = folderTemp + file;
            pdfParser.loadPDF(fileLocation);

            pdfParser.on("pdfParser_dataError",(errData) => {
                console.error(errData.parserError);
                reject(errData);
            });

            pdfParser.on("pdfParser_dataReady",(pdfData) => {
                let t1 = pdfData.formImage.Pages[0].Texts[32].R[0].T.replace(/%20/g," ");
                let t2 = pdfData.formImage.Pages[0].Texts[33].R[0].T.replace(/%20/g," ");
                let t3 = pdfData.formImage.Pages[0].Texts[34].R[0].T.replace(/%20/g," ");
                let t4 = pdfData.formImage.Pages[0].Texts[35].R[0].T.replace(/%20/g," ");
                let t5 = pdfData.formImage.Pages[0].Texts[36].R[0].T.replace(/%20/g," ");
                let t6 = pdfData.formImage.Pages[0].Texts[37].R[0].T.replace(/%20/g," ");
                let t7 = pdfData.formImage.Pages[0].Texts[38].R[0].T.replace(/%20/g," ");
                let t8 = pdfData.formImage.Pages[0].Texts[39].R[0].T.replace(/%20/g," ");
                let t9 = pdfData.formImage.Pages[0].Texts[40].R[0].T.replace(/%20/g," ");
                let textsPdf = [t1,t2,t3,t4,t5,t6,t7,t8,t9];
                let fileWithTexts = {
                    file: fileLocation,texts: textsPdf
                }

                renameFileMatch(fileWithTexts);
                arrayObjs.push(fileWithTexts);
                resolve(fileWithTexts);
            });
        })        
    });
    await Promise.all(promises);
    return arrayObjs;
}
,

您可以在getInformationsPdf()函数中使用Promise

示例

function getInformationsPdf() {
       return new Promise((resolve,reject) => {
           let arrayObjs = [];
           fs.readdirSync(folderTemp).forEach(file => {
                  ...//your code stuff
                if(!fileWithTexts) resolve(arrayObjs);  //handle your exception
                renameFileMatch(fileWithTexts);
                arrayObjs.push(fileWithTexts);
                
           })
     })
}