如何在Node JS中同步执行

问题描述

我是Node.js的新手,我希望下面的代码同步运行。
我想将数据库移到另一个地方,但是我需要等到之前的代码完成。

var exec = require('child_process').exec;
var sql = require('./connectDB');
var regedit = require('regedit');
var fs = require('fs');
var fse = require('fs-extra');

coll = "AT"

if (coll === "AT") {
  coll = "latin1_General_CI_AS"
} else if (coll === "BG") {
  coll = "Cyrillic_General_CI_AS"
} else if (coll === "CZ") {
  coll = "Czech_CI_AS"
} else if (coll === "HU") {
  coll = "Hungarian_CI_AS"
}

console.log("Change of collation");

exec(
  `"c:/Program Files (x86)/Microsoft sql Server/120/Setup Bootstrap/sqlServer2014/setup" /QUIET /ACTION=REBUILDDATABASE /INSTANCENAME=MSsqlSERVER /sqlSYSADMINACCOUNTS=hruza /SAPWD=ES_uni2004 /sqlCOLLATION="${coll}"`,function (err,stdout,stderr) {
    if (err) {
      console.error(`Setting of sql collation error: ${err}`);
      console.log(`${stdout}`);
    }

    exec(
      `net start MSsqlSERVER`,stderr) {
      }
    )
    
    exec(
      `net start sqlbrowser`,stderr) {
      }
    )
    
    exec(
      `net start sqlWriter`,stderr) {
      }
    )

    sql.connectDB(
      `master`,`ALTER DATABASE master MODIFY FILE (NAME = master,FILENAME = 'c:/DB/DATABASE/Data/master.mdf')`,`ALTER DATABASE master MODIFY FILE (NAME = mastlog,FILENAME = 'c:/DB/DATABASE/Data/mastlog.ldf')`,out) {
        if (err) {
          console.error(`Setting of sql collation error: ${err}`);
          console.log("Master DB location changed");
        }

        console.log("Writing registry sql");

        var registryKey = 'HKLM\\SOFTWARE\\WOW6432Node\\Microsoft\\Microsoft sql Server\\MSsql12.MSsqlSERVER\\MSsqlServer\\Parameters';
        const registryValue = {[registryKey]: {
          'sqlArg0': {
            value: `-d$c:\\DB\\Database\\Data\\master.mdf`,type: 'REG_SZ'
          },'sqlArg1': {
            value: '-eC:\\Program Files (x86)\\Microsoft sql Server\\MSsql12.MSsqlSERVER\\MSsql\\Log\\ERRORLOG','sqlArg2': {
            value: `-l$c:\\DB\\Database\\Data\\mastlog.ldf`,type: 'REG_SZ'
          }
        }
      };

      regedit.putValue(registryValue,function(err,result) {
        if (err) console.log(err)
          
        console.log(result);
      });

      console.log("Stop service sql");

      exec(
        `net stop MSsqlSERVER`,stderr) {
        }
      )

      // moving db to another place but I need to wait to prevIoUs code finishs
      fse.move(
        'c:/Program Files (x86)/Microsoft sql Server/MSsql12.MSsqlSERVER/MSsql/DATA/master.mdf','c:/DB/Data/master.mdf',{ overwrite: true }
      )

      fse.move(
        'c:/Program Files (x86)/Microsoft sql Server/MSsql12.MSsqlSERVER/MSsql/DATA/mastlog.ldf','c:/DB/Database/Data/mastlog.ldf',{ overwrite: true }
      )
  });
});

解决方法

最简单的技巧是查看库是否具有promise()方法,如果您很幸运,有时它们也可以。

但是,在不太可能的情况下,您总是可以将回调函数(function(...) { ... })包装在这样的承诺中。

let promiseResult = await new Promise(function(resolve,reject) {
    sql.connectDB(`master`,`ALTER DATABASE master MODIFY FILE (NAME = master,FILENAME = 'c:/DB/DATABASE/Data/master.mdf')`,`ALTER DATABASE master MODIFY FILE (NAME = mastlog,FILENAME = 'c:/DB/DATABASE/Data/mastlog.ldf')`,function (err,out) {
    if (err) return reject(err);
    return resolve(out);
})

您还必须将此代码包装在另一个async函数中

async function yourFunName() {
    let promiseResult = await new Promise(function(resolve,reject) {
        sql.connectDB(`master`,out) {
        if (err) return reject(err);
        return resolve(out);
    })
}

yourFunName().then(data => {
    console.log(data);
}).catch(err => {
    console.error(err);
})
,

回调函数将不等待其中的代码完成。同步代码的最简单方法是将下面的文件移到sql.connectDB的回调函数中。

fse.move('c:/Program Files (x86)/Microsoft SQL Server/MSSQL12.MSSQLSERVER/MSSQL/DATA/master.mdf','c:/DB/Data/master.mdf',{ overwrite: true })


fse.move('c:/Program Files (x86)/Microsoft SQL Server/MSSQL12.MSSQLSERVER/MSSQL/DATA/mastlog.ldf','c:/DB/Database/Data/mastlog.ldf',{ overwrite: true })