同步遍历异步函数

时间:2019-02-13 05:40:26

标签: javascript node.js asynchronous

我有一个功能,可以从oracle数据库,excel文件中读取数据并对数据进行一些操作,然后将结果数据存储在excel文件中。

const app = require('./index.js');
app('ZR_CUSTOMER_INVOICES Functional Specification')
const azureFunction = require('./connections/azureConnection');
const idsFunction = require('./connections/idsconnection');
const xlsFunction = require('./connections/readExcel');
const writeToExcel = require('./connections/writeToExcel');
var azureData;
var idsData;
var xlData;
var xlColumns;
var azureColumns;
var idsColumns;
var resultData;
var table_name;
var file_name='';
function app(fileName){
  file_name=fileName
  xlsFunction(file_name,xlCallback);
}
function xlCallback(xlresult,tName){
  table_name=tName;
  xlData=xlresult
  xlColumns=xlData.map((a,i)=>{
    return a.Columns
  })
  var azquery=`exec sp_columns  ${table_name}`
  azureFunction(azquery,acallback);
}
function acallback(azresult){
  // let table_name=xlData[0]['View Name']
  let idsquery=`select COLUMN_Name from ids_columns where table_id = (select table_id from ids_tables where table_name ='${table_name}')`;
  azureData=azresult;
  azureColumns=azureData.map((a,i)=>{
    return a.value
  })
  idsFunction(idsquery,icallback);
}
function icallback(idsresult){
  idsData=idsresult;
  idsColumns=idsresult.rows.map((a,i)=>{
    return a[0]
  })
  finalFunction()
}
function finalFunction(){
  resultData=xlData.map((a,i)=>{
    if(a.Columns==''){
      return;
    }
    a['inIds?']=idsColumns.includes(a.Columns);
    a['inAzure?']=azureColumns.includes(a.Columns);
    return a;
  })
  resultData=resultData.filter((a,i)=>{
    return a!==undefined;
  })
  // console.log(resultData);
  writeToExcel(resultData,file_name)
  console.log('done');
}

module.exports=app;

这很好。

但是如果我两次对应用程序进行函数调用。

const app = require('./index.js');
app('ZR_CUSTOMER_INVOICES Functional Specification')
app('ZR_CONTACTS Functional Specification')

我只完成一次输出,然后控件也没有中断。

我认为与数据库的连接存在一些问题,因此我想同步进行并检查。

//如果需要任何代码,请评论我。

2 个答案:

答案 0 :(得分:0)

您有一堆变量(例如var azureData;),它们的作用域仅限于模块。

当您两次调用该函数时,两组函数调用将共享这些变量。

特别是,这意味着file_name=fileName会将file_name设置为'ZR_CUSTOMER_INVOICES Functional Specification',然后再设置为'ZR_CONTACTS Functional Specification',并且两个调用将继续使用值为{{ 1}}。

'ZR_CONTACTS Functional Specification' 范围内定义这些变量。然后在app内定义所有需要访问它们的函数,以使变量在它们的作用域之内。

每次对app的调用将具有其自己的变量集,并且它们不会互相覆盖。

答案 1 :(得分:0)

我已经通过回调解决了问题。

const azureFunction = require('./connections/azureConnection');
const idsFunction = require('./connections/idsconnection');
const xlsFunction = require('./connections/readExcel');
const writeToExcel = require('./connections/writeToExcel');
const done = require('./app');
var azureData;
var idsData;
var xlData;
var xlColumns;
var azureColumns;
var idsColumns;
var resultData;
var table_name;
var file_name='';
function app(fileName){
  file_name=fileName
  xlsFunction(file_name,xlCallback);
}
function xlCallback(xlresult,tName){
  table_name=tName;
  xlData=xlresult
  xlColumns=xlData.map((a,i)=>{
    return a.Columns
  })
  var azquery=`exec sp_columns  ${table_name}`
  azureFunction(azquery,acallback);
}
function acallback(azresult){
  // let table_name=xlData[0]['View Name']
  let idsquery=`select COLUMN_Name from ids_columns where table_id = (select table_id from ids_tables where table_name ='${table_name}')`;
  azureData=azresult;
  azureColumns=azureData.map((a,i)=>{
    return a.value
  })
  idsFunction(idsquery,icallback);
}
function icallback(idsresult){
  idsData=idsresult;
  idsColumns=idsresult.rows.map((a,i)=>{
    return a[0]
  })
  finalFunction()
}
function finalFunction(){
  resultData=xlData.map((a,i)=>{
    if(a.Columns==''){
      return;
    }
    a['inIds?']=idsColumns.includes(a.Columns);
    a['inAzure?']=azureColumns.includes(a.Columns);
    return a;
  })
  resultData=resultData.filter((a,i)=>{
    return a!==undefined;
  })
  // console.log(resultData);
  writeToExcel(resultData,file_name)
  console.log('done');
  done.onDone()
}

module.exports=app;
const app = require('./index.js');
app('ZR_CUSTOMER_INVOICES Functional Specification')
function onDone(){
    app('ZR_CONTACTS Functional Specification')
}
exports.onDone=onDone

它奏效了。