我正在使用节点js $ http来处理http post请求,该请求通过邮件和密码使用DB(mongoDB)对用户进行身份验证。
问题是数据库查询需要时间,因此不能与http调用同步。我正在使用req == undefiend返回http,因为我没有等待(使用promise或类似的东西,到db查询完成)。
由于我是JS和节点JS的新手,如果有人可以帮我修复我的代码,我将不胜感激。谢谢!
重要:如果我直接从内部函数发送带有true或false值的req,它将会起作用 - >我知道!但是..我希望它以更通用的方式编写 - 我希望http逻辑不涉及db逻辑。
app.post('/authenticate_user', function(req, res){
var mail = req.body.Mail;
var password = req.body.Password;
res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate, max-age=0");
var isValid=authenticate_user(mail, password);
console.log("isValid-->"+isValid);
// I get undefiend since at this time the db did nor finish...
res.json(isValid);
});
var authenticate_user=function(mail, password){
var query = user_details.find({'Mail': mail});
query.exec( function(err, docs){
if (docs.length==0) {
return false;
}
else{
return(docs[0].Password==password);
}
});
}
答案 0 :(得分:1)
“良好的node.js /事件驱动”方式是不等待。
与使用节点等事件驱动系统时几乎所有其他内容一样,您的函数应该接受一个回调参数,该参数将在计算完成时调用。调用者不应该等待正常意义上的“返回”值,而是发送将处理结果值的例程:
function(query, callback) {
myApi.exec('SomeCommand', function(response) {
// other stuff here...
// bla bla..
callback(response); // this will "return" your value to the original caller
});
}
所以你不要这样使用它:
var returnValue = myFunction(query);
但是像这样:
myFunction(query, function(returnValue) {
// use the return value here instead of like a regular (non-evented) return value
});
答案 1 :(得分:0)
就您的代码而言,这可能是最简单的方法 - 只需将您的HTTP res对象传递到数据库承诺中,并在数据库结果进入后解析它:
app.post('/authenticate_user', function(req, res) {
var mail = req.body.Mail;
var password = req.body.Password;
res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate, max-age=0");
authenticate_user(res, mail, password);
});
var authenticate_user = function(res, mail, password) {
var query = user_details.find({
'Mail': mail
});
query.exec(function(err, docs) {
var isValid = false;
if (docs.length == 0) {
isValid = false;
}
else {
isValid = (docs[0].Password == password);
}
res.json(isValid);
});
};