你的代码的问题
上述方法的问题在于,如果您在每次执行后忘记释放连接,您getDb
就会发生资源泄漏,当您泄漏的资源用完时,最终可能会冻结您的应用程序。
您可能会在一个地方执行以下操作:
var users = getDb().then(function(conn){
return conn.query("SELECT name FROM users");
});
这将泄漏从未关闭的数据库连接。
处理器模式
处置器模式是一种将代码范围与拥有资源耦合的方式。通过将资源绑定到一个作用域,我们可以确保它在我们完成后总是被释放,并且我们不会轻易忘记释放它。它类似于using
C#、with
Python 和 Java 中的 try-with-resource 以及 C++ 中的 RAII。
看起来像:
withResource(function(resource){
return fnThatDoesWorkWithResource(resource); // returns a promise
}).then(function(result){
// resource disposed here
});
在这里应用
如果我们将代码编写为:
function withDb(work){
var _db;
return myDbDriver.getConnection().then(function(db){
_db = db; // keep reference
return work(db); // perform work on db
}).finally(function(){
if (_db)
_db.release();
});
}
我们可以把上面的代码写成:
withDb(function(conn){
return conn.query("SELECT name FROM users");
}).then(function(users){
// connection released here
});
处置器模式的用户示例是sequelize和knex(书架的查询构建器)。也可以将它用于更简单的事情,例如在所有 AJAX 请求完成时隐藏加载程序。
蓝鸟
由于您使用的蓝鸟,它一直致力于Promise.using
与.disposer
内置在功能,让你处理采取/一次你可能要考虑释放多个资源。