What is the promise disposer pattern?

纵饮孤独 提交于 2019-11-26 04:48:57
Benjamin Gruenbaum

The issue with your code

The problem with the above approach is that if you forget releasing the connection after every single time you perform getDb you have a resource leak that might freeze your app eventually when it runs out of the resource you're leaking.

You might, in one place do:

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

Which will leak a database connection that was never closed.


The disposer pattern

The disposer pattern is a way to couple a scope of code with owning the resource. By binding the resource to a scope we make sure it is always released when we're done with it and we can't easily forget to release it. It is similar to using in C#, with in Python and try-with-resource in Java as well as RAII in C++.

It looks like:

 withResource(function(resource){
     return fnThatDoesWorkWithResource(resource); // returns a promise
 }).then(function(result){
    // resource disposed here
 });

Applying it here

If we wrote our code as:

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();
    });
}

We could write our above code as:

 withDb(function(conn){
     return conn.query("SELECT name FROM users");
 }).then(function(users){
     // connection released here
 });

Examples of users of the disposer pattern are sequelize and knex (bookshelf's query builder). It's also possible to use it for simpler things like hiding a loader when all AJAX requests completed for instance.

Bluebird

Since you're using bluebird, it has dedicated Promise.using and .disposer functions built in that let you handle taking/releasing multiple resources at once you might want to consider.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!