nodejs 模块抛出错误但相同的代码在主 js 文件中工作

nodejs module throws error but same code worked in main js file

我想知道为什么这个自定义模块不起作用

模块:

var mariadb = require('mariadb');

class DB{
    constructor(){
        this.db_conn = null;
        this.db_pool = mariadb.createPool({
            host:"localhost",
            user:"root",
            password:"",
            database:"testdatabse"
        });
        this.db_pool.getConnection().then(conn => {
            this.db_conn = conn;
        });
    }
};


module.exports = function(){
    return (new DB()).db_conn;
}

但相同的代码在主 javascript 文件中工作

主文件在这里:

var http = require('http');
var url = require('url');
var mariadb = require('mariadb');
var dbs = require('./modules/mariadb-connector'); //here i am importing the module
var db_conn;
var db = mariadb.createPool({
    host:"localhost",
    user:"root",
    password:"",
    database:"testdatabase"
});
db.getConnection().then(conn => {
    db_conn = conn;
});

console.log(dbs.query("SELECT * FROM array_languages")); //here it's throwing error

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'application/json'});
    console.log(req.url);
    db_conn.query("SELECT * FROM array_languages").then(data => {
        res.write(JSON.stringify(data));
        res.end();
    });
}).listen(8080,"localhost");

错误:

PS D:\Programs\nodejs\test> node index.js
D:\Programs\nodejs\test\index.js:16
console.log(dbs.query("SELECT * FROM array_languages"));
                ^

TypeError: dbs.query is not a function
    at Object.<anonymous> (D:\Programs\nodejs\test\index.js:16:17)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
    at internal/main/run_main_module.js:17:47

这里是我尝试使用这个模块时的错误

console.log(dbs.query("SELECT * FROM array_languages"));

请解释为什么在主 js 文件中工作而不在模块中工作。 有什么办法可以做到这一点

嗯,这不是同一个代码,是吗?您的问题在这里:

        this.db_pool.getConnection().then(conn => {
            this.db_conn = conn;
        });

这是一个异步函数。它会在构造函数 运行 之后完成 运行ning。当 db_connnull.

时,您正在导入 return (new DB()).db_conn

如果您打算将其用作 class,我会创建一个方法 getConnection,它在完成 运行 后从 db_conn 获取值]ning,并导入实例而不是 属性

var dbs = require('./modules/mariadb-connector')

dbs 设置为自定义模块的导出对象,这是 return 新数据库连接器的函数:

function(){
    return (new DB()).db_conn;
}

您可以尝试在设置 dbs 时调用 exports 模块,例如

var dbs = require('./modules/mariadb-connector')();

但是,这留下了 .db_conn 属性 of new DB() 在 promise 回调中异步设置的问题。在模块中要求模块 db-conn 后立即仍然是 null.

需要实施某种形式的异步处理,考虑到目前在获取数据库连接和服务请求以查找数据库之间存在竞争条件数据库。目前建立连接赢得了比赛:这是当连接代码在主模块中时它似乎工作的唯一原因。

异步处理思路大纲:

var http = require('http');
var url = require('url');
var mariadb = require('mariadb');

async function db_conn() {
    let db_pool  = mariadb.createPool({
            host:"localhost",
            user:"root",
            password:"",
            database:"testdatabse"
        });

    const conn = await db_pool.getConnection();
    return conn;
}

db_conn().then( db_conn => {

    http.createServer(function (req, res) {
        res.writeHead(200, {'Content-Type': 'application/json'});
        console.log(req.url);
        db_conn.query("SELECT * FROM array_languages").then(data => {
            res.write(JSON.stringify(data));
            res.end();
        });
    }).listen(8080,"localhost");

})
.catch( err=> {
   console.error( err));
   process.exit(1);
});