Node.js 单件续集
我正在Node.js 单件续集,node.js,aws-lambda,singleton,sequelize.js,serverless-framework,Node.js,Aws Lambda,Singleton,Sequelize.js,Serverless Framework,我正在node.js中使用Sequelize,其思想是使用Singleton模式 阅读关于节点如何使用和一些单例示例 我现在的档案是: const DBManager = (function () { // Instance stores a reference to the Singleton let instance: any; let db: string = null; let user: string; let password: string; let h
node.js
中使用Sequelize
,其思想是使用Singleton
模式
阅读关于节点如何使用和一些单例示例
我现在的档案是:
const DBManager = (function () {
// Instance stores a reference to the Singleton
let instance: any;
let db: string = null;
let user: string;
let password: string;
let host: string;
let sequelize: Sequelize.Sequelize;
function init(bdName: string) {
db = bdName;
user = process.env.MYSQL_DB_USERNAME || 'root';
password = process.env.MYSQL_DB_PASSWORD || 'root';
host = process.env.MYSQL_DB_HOST || 'localhost';
return {
open: () => {
sequelize = new Sequelize(db, user, password, {
host: host,
dialect: 'mysql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
operatorsAliases: false,
logging: !process.env.HIDE_LOGS
});
},
testConnection: () => {
return sequelize.authenticate();
},
getManagerObject: () => {
return sequelize;
},
close: () => {
sequelize.close();
}
};
}
return {
// Get the Singleton instance if one exists
// or create one if it doesn't
getInstance: (bd?: string) => {
if (!instance) {
instance = init(bd);
}
return instance;
}
};
})();
export default DBManager;
因此,正如预期的那样,当我在项目中的任何地方需要此文件时,引用都是相同的,并且工作正常。
我不确定这是否是实现单例模式的正确方法,或者是否有一个已定义和已记录的单例模式,因为官方文档对此没有任何说明。通常不需要显式单例实现。JS模块(特别是CommonJS和ES模块)在正常情况下只评估一次,导出的类实例是有效的单例
也不需要IIFE,因为模块有自己的作用域。因为init
函数没有被重用,所以也可能不需要它。可以简化为:
export default {
open: ...
testConnection: ...
...
};
这种抽象不实用。已经有了sequelize
实例,为自己的方法创建包装器方法并没有什么用处
由于连接在建立后可用,因此导出连接的承诺是有意义的,类似于中所示的承诺
如果配置(数据库名称)在数据库管理器模块中可用,则最好只在适当的位置使用它:
// db.js
const dbName = someConfig.db;
const sequelize = new Sequelize(dbName, ...);
export default sequelize.authenticate().then(() => sequelize);
它的用法如下:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
如果可能存在多个连接,或者导入时配置不可用,则将导出factory函数:
// db.js
export default dbName => {
const sequelize = new Sequelize(dbName, ...);
sequelize.authenticate().then(() => sequelize);
}
单例实例自然由模块处理:
// foo-db.js
import getDbConnection from './db';
export default getFooDbName().then(dbName => getDbConnection(dbName));
用起来像:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
通常不需要显式的单例实现。JS模块(特别是CommonJS和ES模块)在正常情况下只评估一次,导出的类实例是有效的单例
也不需要IIFE,因为模块有自己的作用域。因为init
函数没有被重用,所以也可能不需要它。可以简化为:
export default {
open: ...
testConnection: ...
...
};
这种抽象不实用。已经有了sequelize
实例,为自己的方法创建包装器方法并没有什么用处
由于连接在建立后可用,因此导出连接的承诺是有意义的,类似于中所示的承诺
如果配置(数据库名称)在数据库管理器模块中可用,则最好只在适当的位置使用它:
// db.js
const dbName = someConfig.db;
const sequelize = new Sequelize(dbName, ...);
export default sequelize.authenticate().then(() => sequelize);
它的用法如下:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
如果可能存在多个连接,或者导入时配置不可用,则将导出factory函数:
// db.js
export default dbName => {
const sequelize = new Sequelize(dbName, ...);
sequelize.authenticate().then(() => sequelize);
}
单例实例自然由模块处理:
// foo-db.js
import getDbConnection from './db';
export default getFooDbName().then(dbName => getDbConnection(dbName));
用起来像:
import dbConnection from './db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
import dbConnection from './foo-db';
dbConnection.then(sequelize => { /* all code that depends on the connection */ });
嗨,埃斯特斯。我按照你的例子做了一个实现,看起来不错,但是我有一个考虑因素的用例。我的代码将在aws lambda函数上运行,因此,我需要在每次调用后关闭连接,以允许lambda成功响应。问题是,如果我关闭连接并再次调用相同的函数,它将已经关闭,因此无法查询数据库。这就是在我的示例中对函数进行连接处理的原因。这样,我可以在每次调用函数时调用它,因此每次都会在原始代码中创建连接唯一保持为“singleton”的是db名称。我不确定是否有更好的AWS Lambda方法,但您可以加入答案中显示的两种方法,即导出工厂函数并使用DB配置:export default()=>{/*get DB name from config*/const sequelize=new sequelize(dbName,…);sequelize.authenticate()。然后(()=>sequelize);
。您可以通过调用工厂函数获得连接。然后通过调用sequelize.close()
.hi@estus关闭它。我按照你的例子做了一个实现,看起来不错,但是我有一个考虑因素的用例。我的代码将在aws lambda函数上运行,因此,我需要在每次调用后关闭连接,以允许lambda成功响应。问题是,如果我关闭连接并再次调用相同的函数,它将已经关闭,因此无法查询数据库。这就是在我的示例中对函数进行连接处理的原因。这样,我可以在每次调用函数时调用它,因此每次都会在原始代码中创建连接唯一保持为“singleton”的是db名称。我不确定是否有更好的AWS Lambda方法,但您可以加入答案中显示的两种方法,即导出工厂函数并使用DB配置:export default()=>{/*get DB name from config*/const sequelize=new sequelize(dbName,…);sequelize.authenticate()。然后(()=>sequelize);
。您可以通过调用工厂函数获得连接。然后通过调用sequelize.close()
来关闭它。