我对NodeJS完全陌生,这个问题一直困扰着我好几天。我拉我的头发找到一个有效的解决方案。我试图从数据库中获取信息并将其传递给我稍后从中读取的文本文件。我不能按顺序做。它总是首先读取然后创建它。我不知道应采取什么方式来克服这个问题。任何有效的解决方案/方式都会有很大的帮助。
我的连接文件,用于从数据库中检索信息:
this.getInfo = function() {
return new Promise(function(resolve, reject){
db.query('SELECT ai_code from user_code',
function(err,rows){
if(err)
reject(err);
resolve(rows);
});
});
}
module.exports =
{
getInfo: this.getInfo
}
调用方法接收数据的函数。
function team1Code(){
db.getInfo().then(function(result){
var code = JSON.stringify(result[0]);
var c = json2plain(code, options);
c = c.replace('Ai_code:','');
fs.writeFile('./scr1.js', c, { overwrite: true, encoding: 'ascii' },function (err) {
if (err) return console.log(err);
});
});
}
function team2Code(){
db.getInfo().then(function(result){
var code = JSON.stringify(result[1]);
var c = json2plain(code, options);
c = c.replace('Ai_code:','');
fs.writeFile('./scr2.js', c, { overwrite: true, encoding: 'ascii' },function (err) {
if (err) return console.log(err);
});
});
}
最后,这是我们尝试阅读文件内容的地方。
vmHandler.init = function(apiValues) {
team1Code();
team2Code();
// Team 1
try{
vmHandler.team1.scriptCode = fs.readFileSync('./scr1.js');
vmHandler.team1.script = new vm.Script(vmHandler.team1.scriptCode);
vmHandler.team1.sandbox = { api: new Api(apiValues, 1) }
vmHandler.team1.context = new vm.createContext(vmHandler.team1.sandbox);
}catch(err){}
// Team 2
try {
vmHandler.team2.scriptCode = fs.readFileSync('./scr2.js');
vmHandler.team2.script = new vm.Script(vmHandler.team2.scriptCode);
vmHandler.team2.sandbox = { api: new Api(apiValues, 2) }
vmHandler.team2.context = new vm.createContext(vmHandler.team2.sandbox);
} catch(err) {
console.log("ERROR: " + err);
}
};
答案 0 :(得分:1)
由于函数调用,您正在采取的方法略有不利
team1Code();
team2Code();
在下一个try-catch
块执行之前无法确保完成。这是因为两个调用都是异步的,因此即使它们正在使用promises,下一行也会在它们完成之前执行。 承诺本身是异步的,它们变得容易,任何then
内的所有代码都不会被执行,直到承诺得到解决,但其余的代码将照常执行。所以,这是使用更新代码完成任务的方法。
function writeFile(fileName,data){
return new Promise(function(resolve, reject){
var code = JSON.stringify(data);
var c = json2plain(code, options);
c = c.replace('Ai_code:','');
fs.writeFile(fileName, c, { overwrite: true, encoding: 'ascii' },function (err) {
if(err)
reject(err);
resolve();
});
})
}
//Finally, this is where we try to read the content of the files.
vmHandler.init = function(apiValues) {
var files = ['./scr1.js','./scr2.js'];
db.getInfo().then(function(result){
var allPromise = [];
for(var key in files){
allPromise.push(writeFile(files[key], result[key]));
}
return Promise.all(allPromise);
}).then(function(res){
// Team 1
try{
vmHandler.team1.scriptCode = fs.readFileSync('./scr1.js');
vmHandler.team1.script = new vm.Script(vmHandler.team1.scriptCode);
vmHandler.team1.sandbox = { api: new Api(apiValues, 1) }
vmHandler.team1.context = new vm.createContext(vmHandler.team1.sandbox);
}catch(err){}
// Team 2
try {
vmHandler.team2.scriptCode = fs.readFileSync('./scr2.js');
vmHandler.team2.script = new vm.Script(vmHandler.team2.scriptCode);
vmHandler.team2.sandbox = { api: new Api(apiValues, 2) }
vmHandler.team2.context = new vm.createContext(vmHandler.team2.sandbox);
} catch(err) {
console.log("ERROR: " + err);
}
});
};
答案 1 :(得分:0)
在wmHandler.init函数中,您将启动2个异步操作(查询和存储)并从上述异步操作应该写入的文件中读取。
然而,文件读取是在 2个异步操作开始后立即执行的。因此,期望在写入之前读取文件。
要解决此问题,请让team1Code和team2Code返回自己的Promise,并且在文件写完之前不要读取文件。
team1Code().
.then(team2Code)
.then(readFiles)
其中readFiles是执行文件读取的函数,team1Code,team2Code返回在文件写入时解析的Promises。
This answer解释了Javascript中的异步回调。