#javascript #asynchronous #node-mysql
#javascript #асинхронный #узел-mysql
Вопрос:
У меня есть функция, которая вызывает асинхронную функцию ( connection.query
), я хочу изменить параметр comment
и сохранить измененное значение в переменной res
и вернуть его. Однако проблема в том, что оператор return выполняется до forEach
завершения, внутри которого есть асинхронная функция. Как мне гарантировать, что два оператора console.log("outside:" res);
и return res;
выполняются ТОЛЬКО после выполнения всего, что указано выше.
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;
}
Я попытался сделать это, я создал вторую функцию, которая возвращает значение res
вот так,
function callback(){
return res;
}
и я изменил testComment
, чтобы принять обратный вызов, а затем вернуть его следующим образом,
function testComment(comment, callback){
..all the working..(forEach loop which has a asyn function in it)
return callback();
}
Но здесь проблема в том, что testComment
вернет callback()
перед forEach
завершением, это действительно сбивает меня с толку. Есть ли способ это исправить?
РЕДАКТИРОВАТЬ: Для большего контекста, это то, что делает функция, у меня есть таблица в базе данных, в которой есть список bad_words
и список, good_words
которые заменяют их bad_words
во входной строке ( comments
в данном случае). Параметр comment
должен быть протестирован на bad_words
и заменен соответствующим good_words
.
Комментарии:
1. попробуйте использовать обычный цикл for: //этот цикл является синхронизирующим по своей природе для(var i=0,len=words. длина; я
Ответ №1:
Вы должны использовать что-то вроде:
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);
Или, что более удобно, вам следует использовать 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;
});
Комментарии:
1. Большое вам спасибо, сэр, вы спасли мне жизнь!