bluebirdにはusingというAPIがある。
https://github.com/petkaantonov/bluebird/blob/master/API.md#promiseusingpromisedisposer-promise-promisedisposer-promise--function-handler---promise
これはファイルオープン、DB接続の管理などのリソース管理において、
解放し忘れることを防いでくれる。
以下は上記のURLから抜粋したコード。
using(getConnection(), function(connection) { // Don't leak the `connection` variable anywhere from here // it is only guaranteed to be open while the promise returned from // this callback is still pending return connection.queryAsync("SELECT * FROM TABLE"); // Code that is chained from the promise created in the line above // still has access to `connection` }).then(function(rows) { // The connection has been closed by now console.log(rows); });
then() で 「The connection has been closed by now」というコメントが付いている。
直訳だけど、then()の時点でコネクションがクローズされている。
using を利用することで release() とか close() とかする必要がない。
ちょっと不思議だけど、C#に using が存在して、
それと同じ挙動をするようです。
C# の using をググるとイメージが掴めると思います。
日本語の説明も多いし。
で、using を利用すると、Promise() が返されるまではコネクションは開かれている。
「Promise()が返されるまで」というのは上記の例で言うと、
以下が完了するまでは開かれているということ。
return connection.queryAsync("SELECT * FROM TABLE");
違う言い方をすると、次の then() が実行されるとコネクションはクローズされる。
using を利用することでリソースの解放忘れを防ぐことができるので、
便利っぽいが、
then() でクローズしてしまうので、以下のようにコネクションを開いておきたいときには使えない印象を受ける・・・。
then() でクローズされるとcommitできないから困る。
const db1Master: DbMasterConnection = DbConnector.createInstance().createMaster(DbType.DB1); //トランザクション開始 db1Master.beginTransaction().then((result: boolean) => { //パスワードの暗号化 return AppCrypt.getHashedStr(userPassword); }).then( (hashedPassword: string) => { //登録 return UserRepo.insert(new User(User.ID_FOR_NOT_PUBLISH_AUTO_INCREMENT, userName, hashedPassword, new RecordTime()), db1Master); }).then( (user: User) => { //コミット return [db1Master.commit(), user]; }).spread( (result: boolean, user: User) => { resolve(Promise.resolve(user)); }).catch( (err) => { db1Master.rollback().then( (result: boolean) => { reject(err); }); }).finally( () => { db1Master.close(); });
こんな説明でいーのだろーか・・・。