Ответ 1
Проблема с вашим кодом
Проблема с вышеприведенным подходом заключается в том, что если вы забудете освободить соединение после того, как каждый раз, когда вы выполняете getDb
, у вас есть утечка ресурсов, которая может заморозить ваше приложение в конце концов, когда закончится ресурс, который вы протекаете.
В одном месте вы можете:
var users = getDb().then(function(conn){
return conn.query("SELECT name FROM users");
});
Это приведет к утечке соединения с базой данных, которое никогда не было закрыто.
Шаблон удаления
Шаблон удаления - способ сочетать область кода с владением ресурсом. Связывая ресурс с областью, мы убеждаемся, что он всегда выпущен, когда мы закончили с ним, и мы не можем забыть его освободить. Он похож на using
в С#, with
в Python и try-with-resource в Java, а также на 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 завершены, например.
Bluebird
Поскольку вы используете bluebird, он выделил Promise.using
и .disposer
встроенные функции, позволяющие обрабатывать взятие/освобождение сразу нескольких ресурсов, которые вы, возможно, захотите рассмотреть.