node.js - Synchronous Call : Call 2nd function after 1st function is executed completely -


i stating coding in node.js , might simple question.

trying write xml parser/validator validate xml schema , values against values/ xpath stored in excel sheet.

now once validation function complete want call printresult function print final result. if try call function after first function .. printing variables initial values , if called within first iterating though number of xpaths present in excel sheet , printing result increments.

var mocha = require('mocha');  var assert = require('chai').assert;  var fs = require('fs');  var parsestring = require('xml2js').parsestring;  var xpath = require('xpath');  var dom = require('xmldom').domparser;  var xlsx = require('xlsx');  var excel = require("exceljs");  var should = require('chai').should();  var hashmap = require('hashmap');  var colors = require('colors');  require('/xmlvalidator/dbconnect.js');    var map = new hashmap();  var elementmap = new hashmap();  var resultvalue;    //console.log('hello'.green);    map.set("pass", 0);  map.set("fail", 0);  map.set("invalid_path", 0);    function computeresult(elementpath, result) {    var pass = map.get("pass");    var fail = map.get("fail");    var invalidpath = map.get("invalid_path");      elementmap.set(elementpath, result);      if (result == "pass") {      pass++;      map.set("pass", pass);    } else if (result == "fail") {      fail++;      map.set("fail", fail);    } else {      invalidpath++;      map.set("invalid_path", invalidpath)    }    printresult();  }    function printresult() {    var pass = map.get("pass");    var fail = map.get("fail");    var invalidpath = map.get("invalid_path");    console.log(("pass count :" + pass).green);    console.log(("fail count :" + fail).red);    console.log(("inavlid path :" + invalidpath).yellow);    elementmap.foreach(function(value, key) {      if (value == "invalid_path")        console.log((key + ":" + value).yellow);      else if (value == "fail")        console.log((key + ":" + value).red);      else        console.log(key + ":" + value);    });    }      var workbook = new excel.workbook();  workbook.xlsx.readfile('utils/' + process.argv[2])    .then(function() {      var worksheet = workbook.getworksheet(1);      worksheet.eachrow(function(row, rownumber) {        //console.log(rownumber);        var row = worksheet.getrow(rownumber);        var datapath1 = row.getcell("a").value;        var datapath2 = row.getcell("b").value;        var datapath = datapath1 + datapath2;        //console.log(datapath);        var datavalue = row.getcell("d").value;        var flag = row.getcell("e").value;        //console.log(flag)        //console.log(datavalue);        if (!flag)          validate(datapath, datavalue, rownumber);          //else console.log("not executed" + rownumber)        });        })    function validate(datapath, datavalue, rownumber) {    var fail = 0;    fs.readfile('utils/' + process.argv[3], 'utf8', function(err, data) {      if (err) {        console.log("error error error error ");        return console.log(err);      }      var doc = new dom().parsefromstring(data);      var subid = string(xpath.select1(datapath, doc));      if (subid == "undefined") {        /*console.log('undefined caught');  				  console.log("row number :" + rownumber);*/        var resultvalue = "invalid_path";        computeresult(datapath, resultvalue);      } else {        var subid = xpath.select1(datapath, doc);        var value = subid.lastchild.data;        /*console.log("row number :" + rownumber);  				  console.log("actual value: " + value);  				  console.log("expected value:" + datavalue );*/          if (datavalue == null) {          assert.notequal(value, datavalue, "value not found");          resultvalue = "pass";          computeresult(datapath, resultvalue);        } else {          if (value == datavalue)            resultvalue = "pass";          else resultvalue = "fail";          computeresult(datapath, resultvalue);        }      }    });  }

in code above want call printresult() function after validate function executed (workbook.xlsx.readfile)

can 1 please me out how use done () function or make sync call ?

if fs.readfileasync('utils/' + process.argv[3], 'utf8') can executed once, validate() synchronous , calling printresult() after verification loop trivial.

in main routine, can aggregate 2 promises ...

var promise1 = workbook.xlsx.readfile(); var promise2 = fs.readfileasync(); // requires `fs` promisified.  

... before embarking on verification loop.

promise.all([promise1, promise2]).spread(/* verify here */); 

also whole bunch of tidying can considered, in particular :

  • establishing "pass", "fail" , "invalid_path" constants avoid lots of repetitive string creation,
  • using js plain objects in lieu of hashmap,
  • building map elementmap inside print function.
  • having validate() return result , building elementmap in main routine

here's whole thing, tight can it. may have made few assumptions not many bad ones ...

var mocha = require('mocha'); var assert = require('chai').assert; var promise = require("bluebird"); var fs = promise.promisifyall(require("fs")); // allow bluebird take pain out of promisification. var parsestring = require('xml2js').parsestring; var xpath = require('xpath'); var dom = require('xmldom').domparser; var xlsx = require('xlsx'); var excel = require("exceljs"); var should = require('chai').should(); // var hashmap = require('hashmap'); var colors = require('colors'); require('/xmlvalidator/dbconnect.js');  const pass = "pass"; const fail = "fail"; const invalid_path = "invalid_path";  function printresult(elementmap) {     var key, result,          map = { pass: 0, fail: 0, invalid_path: 0 },         colornames = { pass: 'black', fail: 'red', invalid_path: 'yellow' };     for(key in elementmap) {         result = elementmap[key];         map[(result === pass || result === fail) ? result : invalid_path] += 1;         console.log((key + ": " + result)[colornames[result] || 'black']); // presumably colors can applied associative syntax? if so, code can concise.     }     console.log(("pass count: " + map.pass)[colornames.pass]);     console.log(("fail count: " + map.fail)[colornames.fail]);     console.log(("inavlid path: " + map.invalid_path)[colornames.invalid_path]); }  function validate(doc, datapath, datavalue) {     var subid = xpath.select1(datapath, doc),         value = subid.lastchild.data,         result;     if (string(subid) == "undefined") {         result = invalid_path;     } else {         if (datavalue === null) {             assert.notequal(value, datavalue, "value not found"); // not sure             result = pass;         } else {             result = (value === datavalue) ? pass : fail;         }     }     return result; }  //main routine var workbook = new excel.workbook(); var promise1 = workbook.xlsx.readfile('utils/' + process.argv[2]); // question, workbook.xlsx.readfile() appears return promise. var promise2 = fs.readfileasync('utils/' + process.argv[3], 'utf8');  promise.all([promise1, promise2]).spread(function(data2, data3) {     var worksheet = workbook.getworksheet(1),         doc = new dom().parsefromstring(data3),         elementmap = {};     worksheet.eachrow(function(row, rownumber) {         // var row = worksheet.getrow(rownumber); // row formal variable ???          var datapath, datavalue;         if (!row.getcell('e').value)             datapath = row.getcell('a').value + row.getcell('b').value;             datavalue = row.getcell('d').value;             elementmap[datapath] = validate(doc, datapath, datavalue);     });     printresult(elementmap); }); 

untested may not run @ least can raid code ideas.


Comments

Popular posts from this blog

java - pagination of xlsx file to XSSFworkbook using apache POI -

Unlimited choices in BASH case statement -

apache - How do I stop my index.php being run twice for every user -