Nodejs延迟返回"require"

Fra*_*yer 1 javascript asynchronous require node.js

我的设置如下:

  • Nodejs服务器
  • server.js 要求 utils.js
  • utils.js 将数据从mongodb加载到内存并导出它
  • server.js使用utils.js导出的变量

我担心的问题是mongodb调用是异步的.utils.js在mongodb调用完成之前返回,这意味着server.js在require之后继续执行时将使用未定义的变量.

解决这个问题的最佳方法是什么?我唯一能想到的是将我的server.js代码包装在一个巨大的回调中,并将其传递给进行mongodb调用的函数.对我来说似乎有点乱,有没有更好的方法呢?

码:

server.js
var utils = require("./modules/utils.js");
console.log(utils);
//Do whatever

utils.js
var mods = [];
var db = require("mongojs").connect("localhost", ["modules"]);
db.modules.find({}, function(err, modules){
    mods = modules;
});
module.exports = mods;
Run Code Online (Sandbox Code Playgroud)

Ste*_*her 5

你所指的是"回调地狱".最简单的方法是使用简化它的Promise库.

我使用了一个名为的节点包bluebird.

var mysql = require("mysql");
var hash = require("password-hash");
var Promise = require("bluebird");
var settings = require("../settings");

Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);

var db_config = {
    user:settings.db.user,
    password:settings.db.password,
    database:settings.db.database
};

var con = mysql.createPool(db_config);

function query(sql) {
    return con.getConnectionAsync().then(function(connection) {
        return connection.queryAsync(sql)
        .spread(function(rows,fields) {
            return rows;
        }).finally(function() {
            connection.release();
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

这是一个非常基本的数据库模块,我写了一个使用bluebirdpromisify数据库对象.

以下是它的使用方法.它回报了一个承诺!这样做的好处是,它不仅会返回回调地狱的混乱,它还可以确保您的代码异步运行,并且在事情停止处理之前函数不会返回,就像在这种情况下,数据库查询一样.

function login(user) {
    //check for player existance
    var query = 'SELECT p.name,p.password,p.id, pd.x, pd.y FROM player p INNER JOIN player_data pd ON p.id = pd.id WHERE p.name='+mysql.escape(user);
    return db.select(query).then(function(rows) {
        if (!rows.length) return;
        return [
            rows[0]
        ];
    });
}
Run Code Online (Sandbox Code Playgroud)

注意你如何返回一个promise,这样你就可以调用thenor spread方法来获取你刚刚查询过的那些数据库值,而不必担心rows在你想要使用它时是否会定义它.