这是我在index.js中的一些代码。它正在等待该人访问url.com/proxy然后它加载我的代理页面,这实际上只是一个发回电子邮件和代码的表单。从我的MongoDB数据库中,我使用代码获取用户订单,其中包含我需要的一些信息(例如产品和他们试图获得的消息)。出于某种原因,它似乎在它获取此信息之前做出响应,然后在下次提交表单时保留它。
我的res.send中的换行符(产品+'\ n'+消息)也不起作用,但现在这不是什么大问题。
但是..例如,我第一次填写表格时得到空白回复。第二次,我将得到对第一种形式填写的任何内容的响应,然后第三次生病得到第二次响应。我对Web开发很新,觉得我做的事情显然是错的,但似乎无法弄明白。任何帮助将不胜感激,谢谢。
app.get('/proxy', function(req,res){
res.sendFile(__dirname+ "/views/proxy.html");
});
var message = "";
var product = "";
app.post('/getMessage', function(req,res)
{
returnMsg(req.body.user.code, req.body.user.email);
//res.setHeader('Content-Type', 'text/plain');
res.send(product + "\n" + message);
});
function returnMsg(code, email){
MongoClient.connect(url, function(err, db){
var cursor = db.collection('Orders').find( { "order_id" : Number(code) })
cursor.each(function(err, doc){
assert.equal(err, null);
if (doc!= null)
{
message = doc["message"];
product = doc["product"];
}
else {
console.log("wtf");
// error code here
}
});
console.log(email + " + " + message);
var document = {
"Email" : email,
"Message" : message
}
db.collection("Users").insertOne(document);
db.close();
});
}
答案 0 :(得分:1)
您需要在node.js中阅读有关异步编程工作的大量内容。此代码存在重大设计问题:
所有这些都使服务器无法正常工作。你已经发现了其中一个问题。您的异步响应在您发送响应后完成,因此您最终发送的是先前保存的响应,而不是当前保存的响应。此外,如果多个用户正在使用您的服务器,他们的回复将会互相攻击。
这里的核心设计原则首先是您需要学习如何使用异步操作进行编程。任何使用异步响应并希望将该值返回给调用者的函数都需要接受回调并通过回调传递异步值或返回promise并通过已解析的promise返回值。然后调用者需要使用该回调或承诺在异步值可用时获取异步值,然后仅发送响应。
此外,与请求关联的所有数据都需要保留在请求句柄或请求对象“内部” - 而不是任何模块级别或全局变量。这使得来自一个用户的请求不会干扰来自另一个用户的请求。
要了解如何从包含异步操作的函数返回值,请参阅How do I return the response from an asynchronous call?。
您的代码中最终发生的是这一系列事件:
/getMessage
returnMsg()
res.send()
和message
变量中的任何内容调用product
。db.collection().find()
然后重复cursor
。message
和product
变量(这些值会一直存在,直到下一个请求进入)。在计算代码实际工作方式时,有一些关于你的逻辑的事情尚不清楚。您在message
内分配product
和cursor.each()
。由于cursor.each()
是一个可以运行多次迭代的循环,message
和product
的值实际上是否要在res.send()
中使用?
假设您想要message
循环中的最后product
和cursor.each()
值,您可以这样做:
app.post('/getMessage', function(req, res) {
returnMsg(req.body.user.code, req.body.user.email, function(err, message, product) {
if (err) {
// send some meaningful error response
res.status(500).end();
} else {
res.send(product + "\n" + message);
}
});
});
function returnMsg(code, email, callback) {
let callbackCalled = false;
MongoClient.connect(url, function(err, db) {
if (err) {
return callback(err);
}
var cursor = db.collection('Orders').find({
"order_id": Number(code)
});
var message = "";
var product = "";
cursor.each(function(err, doc) {
if (err) {
if (!callbackCalled) {
callback(err);
callbackCalled = true;
}
} else {
if (doc != null) {
message = doc["message"];
product = doc["product"];
} else {
console.log("wtf");
// error code here
}
}
});
if (message) {
console.log(email + " + " + message);
var document = {
"Email": email,
"Message": message
}
db.collection("Users").insertOne(document);
}
db.close();
if (!callbackCalled) {
callback(null, message, product);
}
});
}
就个人而言,我会使用promises并在数据库中使用promise接口而不是回调。
此代码仍然只是概念性的,因为它还有其他需要处理的问题,例如:
insert.One()
之类的事情完成。