各位好,在异步的方法里我采用了co的方式,具体方式如下:
数据库查询:
query=function (sql,callback){
pool.getConnection(function(err, connection) {
if(err){
console.error("DB connect fail:"+err);
callback(err,null);
}
connection.query("set names "+config.db.charset);//重新设置一下编码类型
connection.query(sql,function(err, rows,fields) {
if (err) {
connection.rollback(function() {
callback(err,null);
});
}
callback(null,rows);
connection.release();
return ;
});
});
}
coQuery=function(sql){
return function(callback) {
query(sql,callback);
};
}
调用时如下:
function getCityList(option,callback){
var sql="select * from tb_city where 1=1";
return db.coQuery(sql,callback);
};
app.get("/getCityList",function(req,res){
co(function*(){
var x=yield getCityList(req.query);
console.log(x);
res.json(x);
})();//报错的这行
});
报错: Can’t set headers after they are sent.请问如何解决
query里面
callback(err,null);
callback(null,rows);
var x=yield getCityList(req.query);
console.log(x);
这里的x应该是第一个参数吧。
还有为啥执行两次啊,这里应该会报错把
co(function*(){
var x=yield getCityList(req.query);
console.log(x);
res.json(x);
})();
@yuyang041060120 单个参数是可以这样写的,console.log(x)是没问题的,我去掉这行也是一样的结果。就第一次访问数据是出来的,再刷新一下就报上面的错误了。
@moxiaobei2 你去掉res.json(x);试试看呢
@yuyang041060120 非常感谢你的回答,我需要好好看看用法。
co要求返回的是promise,thunk或者generator,getCityList并没有返回这些类型,所以co不能处理这种情况。 另外,你的程序结构不正确,所以用普通的callback方式也不能得到正确的结果。
function getCityList(option,callback){
var sql="select * from tb_city where 1=1";
return db.coQuery(sql,callback);
};
db.coQuery传递了两个参数,而在db中定义的只有一个参数。 按照现在的写法,你的程序是不能工作的。
我改进了你的程序,换成promise写法,这样co就可以正常的运行了。我使用了bluebird作为promise的库。
var Promise = require("bluebird");
// Note that the library's classes are not properties of the main export
// so we require and promisifyAll them manually
Promise.promisifyAll(require("mysql/lib/Connection").prototype);
Promise.promisifyAll(require("mysql/lib/Pool").prototype);
function query(sql, cb) {
var rtn = conn.getConnectionAsync()
.then(function() {
return conn.queryAsyn('set query')
})
.then(function() {
return conn.queryAsync(sql)
})
.spread(function(rows, fields) {
return rows;
})
.catch(function(err) {
conn.rollbackAsync();
throw err;
})
.finally(function() {
conn.releaseAsync();
});
return rtn.nodeify(cb);
}
function getCityList(cb) {
var sql = 'select * from tb_city where 1=1';
return query(sql, cb);
}
app.get("/getCityList",function(req,res){
co(function*(){
var x=yield getCityList(req.query);
console.log(x);
res.json(x);
}).catch(function(err) {
next(err);
});
});
@eqiuno 这里确实是自己挖的坑,直接去掉callback参数就可以运行的了,ps:我报错的不在于回调本身,在于co最新版本使用写法不对。愧疚。
/getCitylist 都处理完了, co才执行完,要让express等等你的co啊.