Подтвердить что ты не робот

Какова обезболивающая модель?

В нескольких местах я читал о модели обезвреживания обещаний, но я не могу понять, что это такое. Мне было предложено использовать его в коде, который выглядит следующим образом:

function getDb(){
    return myDbDriver.getConnection();
}

var users = getDb().then(function(conn){
     return conn.query("SELECT name FROM users").finally(function(users){
         conn.release();
     });
});

Какая обезболивающая модель и как она применяется здесь?


Примечание. В native promises я shim .finally как "добавляет обработчики отклонения и выполнения, которые возвращают значение, но выполняют действие". Я использую bluebird в этом случае, если это имеет значение.

4b9b3361

Ответ 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 встроенные функции, позволяющие обрабатывать взятие/освобождение сразу нескольких ресурсов, которые вы, возможно, захотите рассмотреть.