如何从 node.js 中的导出(通过 "require" 导入)模块中的函数 return 取值?

How to return value from a function in a exported (imported through "require") module in node.js?

我有一个通用模块,将被多个应用程序使用。该模块有一个具有多种方法的对象。我通过 require 语句导入对象,但我在理解如何在异步编程模型中获取 returned 值时遇到问题。让我在以下过度简化的伪代码中澄清一下:

文件common_module.js:

var mysql = require('mysql');
exports.f1 = function() {
 var connection_pool = mysql.createPool({host: 'xxx', user:..});
 connection_pool.getConnection(function(err, connection) {
    connection.query('SELECT c1 from t1 where c2 =  ?', value, function(err, rows)  {
                     value_to_return  = rows[0].content; //string type
    });
 });
 return (value_to_return);
}

主要的应用程序是 main.js:

db_getval = require('./common_module.js');
console.log(db_getval.f1());

会一直抱怨value_to_return是未定义的,因为return语句是在没有等待查询完成的情况下执行的(感谢异步编程模型)。虽然这是一个 mysql 查询相关的问题,但对于许多其他场景也是如此。我该如何解决这个问题?我在这里遗漏了一些基本的东西......

在这种情况下,您可以使用承诺或回调。

节点中的回调是处理此类工作的实际方式:

var mysql = require('mysql');
exports.f1 = function (cb) {
    var connection_pool = mysql.createPool({
        host: 'xxx',
        user: ..
    });
    connection_pool.getConnection(function (err, connection) {
        if (err) {
            return cb(err);
        }
        connection.query('SELECT c1 from t1 where c2 =  ?', value, function (err, rows) {
            if (err) {
                return cb(err);
            }
            cb(null, rows[0].content);
        });
    });
};

// usage...
theModule(function (err, result) {
    console.log(err, result);
});

也就是说,随着在节点 0.12 中引入承诺,由于更强大的错误处理,承诺变得越来越流行。 (链接也很有用)

var mysql = require('mysql');
exports.f1 = function (cb) {
    return new Promise(function (resolve) {
        var connection_pool = mysql.createPool({
            host: 'xxx',
            user: ..
        });
        connection_pool.getConnection(function (err, connection) {
            if (err) {
                throw err;
            }
            connection.query('SELECT c1 from t1 where c2 =  ?', value, function (err, rows) {
                if (err) {
                    throw err;
                }
                resolve(rows[0].content);
            });
        });
    });
};

// usage...

theModule().then(function (result) {
    console.log(result);
}).catch(function (err) {
    console.log(err, err.stack);
});