首页 > 解决方案 > 跨文件共享变量,而无需在 Node.js 中创建它们的副本

问题描述

我有我的 mysql 连接database.js和一个断开处理程序,以便在断开连接时重新启动连接。看起来像这样:

const mysql = require('mysql');
function handleDisconnect() {
 con = mysql.createConnection({
   host: "host",
   user: "user",
   password: "pass",
   database: "db",
   debug: false
 }); 

 con.connect(function(err) {              
   if(err) {                                     
     setTimeout(handleDisconnect, 2000, con); 
   }                                    
 });                                     

 con.on('error', function(err) {
   if(err.code === 'PROTOCOL_CONNECTION_LOST') { 
     handleDisconnect();                         
   } else {                                      
     throw err;                                  
   }
 });

}

handleDisconnect();


module.exports = {
  con,
}

我想在多个文件中使用相同的连接。例如在test.js

var con = require('database.js').con;
con.query(sql, function (err, result) {
    if (err) {
        console.log("ERROR");
    }
});

但是,这会创建连接的本地副本,并且当连接断开时,该handleDisconnect函数不会重新启动此连接。解决此问题的最佳方法是什么?

标签: mysqlnode.js

解决方案


对象由指针共享,因此只要您始终.con通过对象引用属性,并且只要操作该con属性的人也更改了导出对象中的那个,它就应该起作用。因此,将您的导入代码更改为:

var dbInfo = require('database.js');
dbInfo.con.query(sql, function (err, result) {
    if (err) {
        console.log("ERROR");
    }
});

然后,无论何时con更新属性,只要您通过dbInfo对象引用它(并且不要制作自己的本地副本),您就会看到导出属性的最新值。

当您这样做时,dbInfo指向您在源模块中导出的完全相同的对象。因此,如果您的源模块更改或更新该.conn对象的属性,您与之共享的任何其他模块也将看到该更新的属性。

请注意,您必须更改导出模块中的代码,以使导出的对象也保持最新的值con。您将需要保存您导出的对象的副本(或从 引用它module.exports)并确保它module.exports.con始终具有您希望每个人都使用的最新值。不要将新对象分配给module.exports. 只需更新.con已经存在的对象的属性,因为那是已经导出的对象。

function handleDisconnect() {
 con = module.exports.con = mysql.createConnection({
   host: "host",
   user: "user",
   password: "pass",
   database: "db",
   debug: false
 }); 

如果您需要准确地知道连接何时更改,您可以导出一个EventEmitter对象并在值更改时在该发射器上发出一个事件,conn以便任何使用它的人都可以侦听该事件并动态知道值何时更新。


推荐阅读