0

我刚开始编写 node.js 代码。

我正在编写一个从pdf文件中提取数据的代码,将其清理并存储在数据库中(使用couchdb并使用nano库访问它)。

问题是调用是异步进行的……所以数据库获取调用(我在清理过程中进行了一些获取调用以获取一些附属文件)仅在程序运行后才完成,导致变量未定义。有没有办法解决?

我在下面复制了我的代码

const fs = require('fs');

const os = require('os');

var couchDB = require('couch-db').CouchDB;

var pdf_table_extractor = require('pdf-table-extractor');

const filename = "PQ-PRI-0005-1806-01-0000_quoteSlipForLIBVIDGI1.pdf"

var nano = require('nano')('https://couchadmin:difficulttoguessmypassword@dbdev.perilwise.com');



var server = new couchDB('https://db.url.com');

server.auth("admin","admin");

var db = nano.db.use('pwfb');

var temp = [];

//New callView function
async function callView(){
try{

    const doc = await view('liabilitymdm','pi');
    for (var i =0; i<doc.rows.length;i++){
        tmp.push(doc.rows[i]);
    };
    return doc;
} catch(e){
    console.log(e);
};

};

function suc(result){
    let ttmp = [];
    console.log(result);
    var pageTables = result.pageTables;
    var firstPageTables = pageTables[0].tables;
    ttmp = callView();
    //this console log shows Promise { <pending> }
    console.log(ttmp)
    for (var k = 0; k < firstPageTables.length; k++) {
     var temp = firstPageTables[k];
     if (temp.length > 0) {
      dump.push(temp);
        }
    }
    // console.log(dump);
    var insurer = filename.substr(37,8);
    read_quote_slip(insurer,dump);
}


var read_quote_slip = (insurer,data) => {
    console.log("read_quote_slip correctly entered");
    var finOut = {};
    if (insurer === "LIBVIDGI"){
        finOut.insurer = insurer;
        finOut.policyType = data[2][0].replace(/Quotation  for/g,"");
        finOut.natureOfWork = data[13][3];
        let dedpos = indexGetter(data, "Deductible")[0];
        finOut.deductible = data[dedpos+1][0];
        let cov = indexGetter(data, "Coverage Territory and Jurisdiction")[0];
        finOut.coverageTerritory = data[cov+1][0].replace(/Territory/g,"");
        finOut.coverageJurisdiction = data[cov+2][0].replace(/Jurisdiction/g,"");
        let ext = indexGetter(data,"Extensions")[0];
        finOut.coverage = data[ext+1][0].split(/\r?\n/);
        let majexc = indexGetter(data,"Major Exclusions")[0];
        finOut.exclusions = data[majexc+1][0].split(/\r?\n/);
        let prdtl = indexGetter(data,"Description")[0];
        let prm = premiumcompute(data,prdtl,dedpos);
        finOut.premium = prm;
        finCleaned = libvidgi_cleaned(finOut);
        // console.log(finCleaned);
    }
}

var indexGetter = (words,toFind) => {
    var finindex = [];
    for (var i = 0; i < words.length; i++){
        for (var j = 0; j < words[i].length; j++){
            if(words[i][j].indexOf(toFind) >=0 ){
                finindex.push(i);

    }
  }
}
    return finindex;
}


var premiumcompute = (data, from, to) => {
    let finprem = [];
    let numbop = to - from - 2;
    let incr = 0;
    for (var i = from+2; i < to; i++){
        let pr = {};
        pr.option = incr+1;
        pr.sumInsured = data[i][2].replace(/ /g,"");
        pr.premium = data[i][data[i].length - 1].replace(/ /g,"");
        finprem.push(pr);
        incr +=1;
    }
    return finprem;
}


var libvidgi_cleaned = (finOut) => {

    return finOut;

}

var fal = (result) => {
    console.log(result);
    console.log("there was an error");
}


var readPDFFile = function(filename){
    //Decide which insurer from the filename
    // console.log(filename);
    console.log(filename.substr(37,8)+"Printed on line 38");
    insurer = filename.substr(37,8)
    pdf_table_extractor(filename, (result) => {suc(result)} , fal);

    }



var libvidgi_data_extract = (data) => {
    console.log(data);
    let arr = data.pageTables.tables;
    for (var i = 0; i <= arr.length; i++ ){
        console.log(arr[i]);
    }
}

readPDFFile(filename);
4

2 回答 2

2

此答案假设您使用的是 Node.js > v7.6

由于db.view接受回调,并且您希望等待它完成,因此一种解决方案是promisify它 - 意思是将它变成一个promisewhich can be awaited。你可以使用像Bluebird这样的库,甚至可以使用 Node 的内置promisify util。然后你可以重写callViews

const {promisify} = require('util');

const view = promisify(db.view);

async function callView() {
    try {
        const doc = await view('liabilitymdm', 'pi');
        // the async operation is now guaranteed to be done
        // (if there is an error it will be caught by the catch clause)
        for (var i = 0; i < doc.rows.length; i++) {
            temp.push(doc.rows[i]);
        }
        console.log(temp);
    } catch (e) {

    }
}

如果你没有使用 Node.js > v7.6(并且不能使用async\await你仍然可以使用 Promise,通过使用他们的then方法:

const {promisify} = require('util');

const view = promisify(db.view);

function callView() {
    view('liabilitymdm', 'pi')
        .then(doc => {
            for (var i = 0; i < doc.rows.length; i++) {
                temp.push(doc.rows[i]);
            }
            console.log(temp);
            return temp;
        })
        .then(temp => {
            console.log(temp);
        })
        .catch(e => {});
}

注意 first 如何then返回在 later 中使用的东西then

于 2018-07-16T05:55:56.710 回答
1

要让 Node 异步运行,可以使用关键字asyncawait。他们是这样工作的:

async function doSomething () {
    const formattedData = formatData();
    const result = await db.postToDatabase(formattedData);
    // the below will not happen until the above line is finished
    doSomethingElse(result);
}

在 Node 中让函数异步执行非常简单。只需将async关键字放在函数定义的开头,然后放在await要阻止执行直到完成的任何内容的前面。

于 2018-07-16T05:33:15.310 回答