Javascript:异步函数混淆

时间:2016-10-20 06:48:33

标签: javascript asynchronous node-mysql

我有一个调用异步函数(connection.query)的函数,我想修改参数comment并将修改后的值存储在变量res中并返回它。但问题是在forEach完成之前正在执行return语句,其中有一个异步函数。如何确保两个语句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 个答案:

答案 0 :(得分:2)

你应该使用类似的东西:

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);

或者更方便的是,你应该使用蓝鸟:)

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;
});