Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
79 views
in Technique[技术] by (71.8m points)

javascript - What is the promise disposer pattern?

I've read about the promise disposer pattern in several places but I can't figure out what it is. It was suggested to me to use it in code that looks like:

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

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

What's the promise disposer pattern and how does it apply here?


Note - in native promises, I shim .finally as "add both rejection and fulfillment handlers that return the value but perform an action". I'm using bluebird in this case if it matters.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...