Reputation: 1243
I'm entirely new to NodeJS and this problem has been bugging me for days now. I'm pulling my hairs to find a working solution. I'm trying to get information from the database and pass it to a text file where I later read from it. I cannot do it sequentially. It always reads it first and then creates it. I don't know what way I should take to overcome the issue. Any working solution/ways will help tremendously.
My connection file that retrieves information from the database:
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
}
Functions that calls the method to receive data.
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);
});
});
}
Finally, this is where we try to read the content of the files.
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);
}
};
Upvotes: 0
Views: 1130
Reputation: 459
The approach you are taking is slightly unfavorable since the function calls
team1Code();
team2Code();
doesn't make sure to accomplish before the next try-catch
block gets executed. This is because both the calls are asynchronous hence the next lines get executed before they finish even though they are working with promises. promises themselves are asynchronous, what they make easy is all the code inside any then
won't be executed until the promises get settled but the rest of the code will be executed as usual. So, here is the way to do your tasks with updated code.
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);
}
});
};
Upvotes: 1
Reputation: 529
In the wmHandler.init function, you are starting 2 asynchronous operations (querying and storing) and reading from the files that the aforementioned async operations should write.
However, the file reading is performed right after the 2 async operations are started. Therefore, it is expected that the files are read before written.
To resolve this, make team1Code and team2Code return Promises of their own, and do not read the files until they have been written.
team1Code().
.then(team2Code)
.then(readFiles)
Where readFiles is the function that does the file reading, and team1Code, team2Code return Promises that resolve when the files are written.
This answer explains the asynchronous callbacks in Javascript.
Upvotes: 0