web-dev-qa-db-ja.com

プロミスディスポーザーパターンとは何ですか?

Promise Disposerのパターンについていくつか読んだことがありますが、それが何かわかりません。次のようなコードで使用することが推奨されました。

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

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

promise disposerパターンとは何ですか、ここでどのように適用されますか?


注-ネイティブプロミスでは、シム.finally as "値を返すがアクションを実行する拒否ハンドラーとフルフィルメントハンドラーの両方を追加します"。この場合、問題がある場合はbluebirdを使用しています。

38

コードの問題

上記のアプローチの問題は、getDbを実行するたびに接続を解放するのを忘れると、リークしているリソースが不足すると、最終的にアプリがフリーズする可能性があるリソースリークが発生することです。

あなたは、一箇所で行うかもしれません:

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

閉じられなかったデータベース接続をリークします。


ディスポーザパターン

ディスポーザパターンは、コードのスコープをリソースの所有と結び付ける方法です。リソースをスコープにバインドすることで、リソースを使い終わったときに常に解放されるようにし、解放を忘れることが簡単にできます。これは、C#のusing、Pythonのwith、および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 (bookshelfのクエリビルダー)です。たとえば、すべてのAJAX要求が完了したときにローダーを非表示にするなど、より単純なものに使用することもできます。

青い鳥

Bluebirdを使用しているため、専用の Promise.using および .disposer 複数のリソースの取得/解放を一度に処理できるようにする組み込みの関数。

44