node-mysqlのコールバック地獄をthunkifyでなんとかする

Node.js は –harmony を付けて起動、 io.js ならそのまま使えるのでちょろい。

まず、node-mysql (node-mysql2) の createConnection を使う場合。そこまで変なことしないで thunkify(db.query.bind(db)) にだけ気をつけたらいけます。
ググるとこの方法使ってるのよく見ます。

var mysql    = require('mysql2'),
    thunkify = require('thunkify'),
    co       = require('co');

var db = mysql.createConnection({host: '***', user: '***', password: '***'}),
    query = thunkify(db.query.bind(db));

co(function* () {
    var res = yield query('SELECT * FROM hoge');
    console.log(res);
    db.end();
})

そして、createPoolを使う場合。
pool.getConnection(function(err, db){}) をやってから thunkify(db.query.bind(db)) とするのでちょっと面倒臭いです。

// pool connection 普通のやつ

var pool = mysql.createPool({ ... });

pool.getConnection(function(err, db) {
    db.query(' ... ', function(e, res) {
        console.log(res);
    });
    db.release();
});

このなんかすっきりしないコールバックを下のような感じにすれば、それなりに便利な書き方ができるんじゃないでしょうか。

// pool connection + thunkify

var mysql    = require('mysql2'),
    thunkify = require('thunkify'),
    co       = require('co'),
    pool;

function* getConn() {
    if (!pool) pool = mysql.createPool({host: '***', user: '***', password: '***'});
    var db    = yield thunkify(pool.getConnection.bind(pool))(),
        query = thunkify(db.query.bind(db));

    // db.query を残したまま ES6 generator 用の db.exec を作る
    db.exec = function* () {
        return yield query.apply(null, arguments);
    }
    return db;
}

co(function* () {
    var db  = yield getConn(),
        res = yield db.exec('SELECT * FROM hoge');

    console.log(res);
    db.release();
})

ちょっと長くなったような気もしますが、 co(function* () … の中身がスッキリして見やすくなりました。
今使ってるio.jsのオレオレRSSリーダーでcreateConnectionよりcreatePoolの方がほんの少し速いので、しばらくこれでいこうかなと。

コメントを残す

メールアドレスが公開されることはありません。