我对nodejs很陌生,我在理解如何使用mysql连接对象方面遇到了一些困难。
我的问题不在于代码,而在于设计模式。
假设我有一个用户模块
module.exports = function(){
return{
id: "",
load: function(id){
var sql = 'SELECT * from users where id = '+ DB.escape(id);
console.log(1);
DB.query(sql, function (err, rows) {
this.id = rows[0].id; // not working
console.log(rows[0].id); // prints the id 4
console.log(2);
});
console.log(3);
}
}
}
从模块外部运行下一个代码
var user = require('../modules/user');
var selected_user = user();
console.log("entering users me route");
selected_user.load(4);
console.log("user id is " + selected_user.id); //This does not print the id 4
当我运行代码时,控制台记录1,然后是3,然后是2。 这是由于节点js的异步流程。
但是,如果我正在构建一个网站,并且在将HTML发送到浏览器之前我需要结束查询以填充我的用户对象???
这样做的正确方法是什么?
此外,当我尝试在数据库中收到的id中填充用户的id属性时,它不起作用。
有什么想法吗?
由于
答案 0 :(得分:3)
有几种方法可以做到这一点。我会选择Promises。
假设您有一个异步函数“getUsers”。 它看起来像这样:
function getUsers() {
longQuery(function(err, result){
// What to do with result?
});
您需要重写它才能使用结果。 我们试试吧:
function getUsers() {
return new Promise(function(resolve, reject) {
longQuery(function(err, result){
if(err) reject(err)
else resolve(result)
});
});
现在这个函数返回一个promise。我们如何处理这一承诺?
function handleRequest(req, res) {
getUsers().then(function(result) {
// Do stuff with result
res.send(myProcessedData);
}).catch(function(err) {console.log(err)};
}
这也可以通过回调来完成,将响应对象作为参数传递给查询函数,以及许多其他方法,但我认为promises是一种非常优雅的方式来处理它。
答案 1 :(得分:0)
this.id = rows[0].id; // not working
上述行无法正常工作,因为您要从回调函数中将其设置为this.id
。当您进入回调函数this
时,并不意味着主对象中的this
。
有关此内容的更多讨论:请参阅How to access the correct `this` context inside a callback?
要解决javascript的异步性质,您可以使用promise来表示matanso的答案,也可以将回调函数传递给load方法。因此,当您获得所需的所有数据时,load: function(id)
方法将为load: function(id, callbackFunction)
并调用回调函数。