我的节点工作器中有一个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' }
},
答案 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的帮助。这家伙真的救了我一天!