追加到匿名函数内部的对象

Appending to object inside of anonymous function

本文关键字:内部 对象 函数 追加      更新时间:2023-09-26

我正试图将数据库查询的结果附加到一个表中,如下所示:

function foo() {
    var result = {};
    pool.getConnection(function(err, connection) {
        if(err) {
            console.log("Problem establishing connection with the database");
            return;
        }
        var tables = ["first", "second", "third"];
        _.forEach(tables, function(table) {
            var query = "SELECT * FROM " + table;
            connection.query(query, function(err, data) {
                if(!err) {
                    result[table] = data;
                } else {
                    console.log("Problem performing query '"%s'"", query);
                }
            });
        });
    });
    return result;
}

返回的结果为空,但在forEach内部,它正在被填充。我可以通过在循环中添加日志消息来证明这一点。

我只能认为这是一个作用域问题,但当我将结果更改为属性(this.result)并尝试从循环中分配给它时,我得到了相同的结果。我在函数开始时添加了var that = this;,并在循环中分配给that.result,从而确保使用了正确的this实例。

这不是范围问题,而是时间问题。

您试图在填充result之前返回result,因为匿名函数中的代码要在foo函数返回之后才能运行。它是异步。我希望query调用也是异步的。

由于foo依赖于异步的东西来完成它的工作,所以它不能返回结果。它必须做getConnectionquery所做的事情:接受一个回调函数,稍后它将调用该函数并得到结果。

这里有一种方法可以做到这一点,请参阅代码注释:

function foo(callback) { // <== Note `callback`
    pool.getConnection(function(err, connection) {
        if(err) {
            console.log("Problem establishing connection with the database");
            callback(null); // Do the callback, with a flag value for failure
            return;
        }
        var tables = ["first", "second", "third"];
        var result = {};
        var results = 0; // Remember how many results we've seen
        _.forEach(tables, function(table) {
            var query = "SELECT * FROM " + table;
            connection.query(query, function(err, data) {
                if(!err) {
                    result[table] = data;
                } else {
                    console.log("Problem performing query '"%s'"", query);
                    result[table] = null; // Flag value for failure
                }
                if (++results === tables.length) {
                    // We're done, issue the callback
                    callback(results);
                }
            });
        });
    });
}

因为查询函数是异步的,所以当代码第一次运行时,它会发送查询,然后返回空白对象,因为查询尚未返回。

当查询返回时,应该填写该对象的属性,但此时您需要运行一些代码才能"查看"它。如果您希望代码从该函数返回填充的对象,您会感到失望。:-)