I have a function which calls an asynchronous function (connection.query
), I want to modify the parameter comment
and store the modified value in variable res
and return it. However the problem is that the return statement is being executed before the forEach
finishes, inside of which there's an asynchronous function. How do I ensure that the two statements console.log("outside:" + res);
and return res;
happen ONLY after everything above it is done executing.
var res = "";
function testComment(comment) {
var words = comment.split(" ");
words.forEach(function(word, i){
(function(index){
connection.query('select good_words from words where bad_words = ' + connection.escape(word), function(err, result){
if(err){
console.log(err);
return;
}
if(result.length != 0){
this.res = comment.replace(word, result[0].good_words);
console.log("inside:" + this.res);
}
});
})(i);
});
console.log("outside:" + this.res);
return this.res;
}
I tried doing this, I created a second function which returns the value res
like so,
function callback(){
return res;
}
and I modified testComment
to accept a callback and then return it like this,
function testComment(comment, callback){
..all the working..(forEach loop which has a asyn function in it)
return callback();
}
But here the problem is that testComment
would return the callback()
before forEach
finishes, this is really confusing me. Any way to fix this?
EDIT : For more context, this is what the function does,
I have a table in a database which has a list of bad_words
and a list of good_words
which replace these bad_words
in the input string (comments
in this case). The parameter comment
is to be tested for the bad_words
and replaced by the corresponding good_words
.
You should use something like:
var wordsProcessed = 0;
(function(index){
connection.query('select good_words from words where bad_words = ' + connection.escape(word), function(err, result){
wordsProcessed++;
if(err){
console.log(err);
return;
}
if(result.length != 0){
this.res = comment.replace(word, result[0].good_words);
console.log("inside:" + this.res);
}
if(wordsProcessed >= words.length){
//THIS IS WHERE YOU RETURN YOUR RES
}
});
})(i);
Or more conveniently, you should use bluebird :)
var Promise = require('bluebird');
var promiseArray = words.map(function(word){
return new Promise(function(resolve, reject){
connection.query('select good_words from words where bad_words = ' + connection.escape(word), function(err, result){
if(err) reject(err);
else resolve(result);
});
});
});
Promise.all(promiseArray).then(function(result){
return this.res;
});