使节点等待数据库调用完成

时间:2018-07-14 10:22:29

标签: node.js couchdb couchdb-nano

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

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

问题在于调用是异步进行的...因此,数据库get调用(在清理过程中我进行了一些get调用以获取一些关联文件)仅在程序运行后才完成,导致变量未定义。有什么办法解决吗?

我在下面复制了我的代码

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);

2 个答案:

答案 0 :(得分:2)

此答案假定您正在使用Node.js> v7.6

由于db.view接受了回调,并且您希望等待其完成,因此一种解决方案将是promisify,这意味着将其转换为promise可以是{ {1}}。您可以使用Bluebird之类的库,甚至可以使用Node的内置promisify util。然后,您可以重写awaited

callViews

如果您未使用Node.js> v7.6 (并且无法使用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) { } } ,则仍可以通过使用其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 => {}); } 会如何返回后来的then中使用的内容。

答案 1 :(得分: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放在要阻止执行直到完成的所有内容的前面。