节点mysql和promises

时间:2014-09-29 22:02:47

标签: mysql node.js

我的节点工作器中有一个db模块。我所需要的就是直接,没有回调。查询方法仍然返回 undefined 。我想我在这段代码中做了一些非常错误的事情,但我从未在一个地方见过完整的承诺。

db: {
    init: function (parent) {
        var self = this;
        self.parent = parent;
        self.pool = mysql.createPool({
            host: self.parent.cfg['mysql']['host'].replace(/"/g, ''),
            user: self.parent.cfg['mysql']['username'].replace(/"/g, ''),
            port: self.parent.cfg['mysql']['port'].replace(/"/g, ''),
            password: self.parent.cfg['mysql']['password'].replace(/"/g, ''),
            database: self.parent.cfg['mysql']['db'].replace(/"/g, '')
        });
        self._query = Q.nbind(self.__query, self);
    },
    query: function (query, params) {
        var self = this;
        return self._query(query, params).then(function (rows) {
            return rows;
        }).catch(function(err){
            return err;
        }).done();
    },
    __query: function (query, params) {
        var self = this, deferred;
        deferred = Q.defer();
        query = params ? mysql.format(query, params) : query;
        //console.log(query);
        self.pool.getConnection(function (err, connection) {
            if (err) {
                deferred.reject(err);
            }
            connection.query(query, function (err, rows) {
                connection.release();
                if (err) {
                    deferred.reject(err);
                }
                deferred.resolve(rows);
            });
        });
        return deferred.promise;
    }
}

deferred of deferred.promise

最有可能的是Q.nbind在这里没有必要,无论如何我抛弃了所有东西而deferred.promise是一个对象{state:'pending'}。所以我认为魔鬼在__query函数中。

加入

query: function (query, params) {
    var self = this;
    return self._query(query, params).then(function (rows) {
        console.log(rows);
        return rows;
    }).catch(function(err){
        return err;
    }).done();
}

它将行放入控制台,但不返回它。一个人声称这样的结构有效:

function getKey(key) {
    return r.get(dbkey(key)).then(function(x) {
        return x && parseInt(x, 10);
    });
}

再次添加

是的,删除done()是有道理的。但它仍然返回{state:'pending'}。可能问题在于我调用查询的方式吗?

test: function () {
    var self = this;
    var s = self.db.query(self.testQuery);
    console.log(s); // { state: 'pending' }
},

2 个答案:

答案 0 :(得分:1)

我相信你的问题是你如何使用Q.nbind。它用于创建节点样式回调函数的函数(错误,结果...... 您正在使用延迟在__query函数中处理此问题。所以我认为你应该直接使用__query,你就会开展业务。当我回到计算机上时,我会发布一个代码示例。

答案 1 :(得分:0)

好的,解决方案

db: {
    init: function (parent) {
        var self = this;
        self.parent = parent;
        self.pool = mysql.createPool({
            host: self.parent.cfg['mysql']['host'].replace(/"/g, ''),
            user: self.parent.cfg['mysql']['username'].replace(/"/g, ''),
            port: self.parent.cfg['mysql']['port'].replace(/"/g, ''),
            password: self.parent.cfg['mysql']['password'].replace(/"/g, ''),
            database: self.parent.cfg['mysql']['db'].replace(/"/g, '')
        });
    },
    query: function (query, params) {
        var self = this;
        return self._query(query, params).then(function (rows) {
            return rows;
        }).catch(function (err) {
            return err;
        });
    },
    _query: function (query, params) {
        var self = this, deferred;
        deferred = Q.defer();
        query = params ? mysql.format(query, params) : query;
        //console.log(query);
        self.pool.getConnection(function (err, connection) {
            if (err) {
                deferred.reject(err);
            }
            connection.query(query, function (err, rows) {
                connection.release();
                if (err) {
                    deferred.reject(err);
                }
                deferred.resolve(rows);
            });
        });
        return deferred.promise;
    }
}

如何称呼它:

test: function () {
    var self = this;

    Q.async(function*() {
        var s = yield self.db.query(self.testsql);
        console.log(s); // it is real rows
    })().done();
},

这是非常有用的东西,你可以编写返回promises的方法,然后在一个你想要的地方使用它们:

Q.async(function*() {
    var device = yield self.modules.ami.device.get('123');
    var ext = yield self.modules.ami.extension.get('123');
})().done();

ami.device.get和ami.extension.get方法返回db.query promises:

get: function(id){
    var self = this;
    id = parseInt(id);
    return self.top.db.query(self.select + "WHERE (`ami_device`.`id` = ?)", [id]);
}

我要感谢Gordon Bockus的帮助。这家伙真的救了我一天!