NodeJS routing -
NodeJS routing -
摘要:
我调用了下面的代码一次,下次调用时一切都很好。我在代码下面得到了错误,然后我需要重新启动服务器才能使其工作,但同样,它只工作一次。
注意:
我使用eventEmitter的原因是,如果我用mongoose嵌套两个db请求,它将先做parent,然后做child,所以我必须确保第一个请求完成,才能运行第二个请求。但这不是代码工作的问题,而是我第一次运行它。以前从未遇到过这个问题,我真的很好奇发生了什么
代码:
// loads people user has chatted with
router.get('/loadUserChats', function(req, res) {
var hostID = req.query.id;
let list = [];
let readyToSend = true;
// gets photos for each user in the 'list'
eventEmitter.on('addPictureToObjects', function() {
list.forEach(function(listItem, i) {
User.findOne({_id: listItem.id}, 'photo', function(err, guest) {
listItem.photo = guest.photo;
// if this is the last one send json object back
if (i+1 == list.length) {
res.json({list: list});
}
});
});
});
// get the user
User.findOne({_id: hostID}, function(err, user) {
// checks if user has chatted at all
if (user.chat) {
// loops through the chat
user.chat.forEach(function(chat) {
var photoURL = "";
console.log(chat.user);
// push the chat info so later we can load messages
// by its ID
list.push({
id: chat.user.id,
name: chat.user.name
});
});
// okay, now that we are done looping lets add photos
// to each one of those so it looks better
eventEmitter.emit('addPictureToObjects');
}
});
});
错误:
events.js:160
throw er; // Unhandled 'error' event
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
at ServerResponse.header (/home/knox97/Documents/agro/node_modules/express/lib/response.js:719:10)
at ServerResponse.json (/home/knox97/Documents/agro/node_modules/express/lib/response.js:247:10)
at /home/knox97/Documents/agro/routes/api.js:249:10
at Query.<anonymous> (/home/knox97/Documents/agro/node_modules/mongoose/lib/model.js:3357:16)
at /home/knox97/Documents/agro/node_modules/kareem/index.js:259:21
at /home/knox97/Documents/agro/node_modules/kareem/index.js:127:16
at _combinedTickCallback (internal/process/next_tick.js:67:7)
at process._tickCallback (internal/process/next_tick.js:98:9)
事实上,我通过重写代码并将照片草签添加到聊天列表对象中来解决了这个问题,这样我就不必手动添加照片了,这是一个更快、更聪明的解决方案,但我真的很好奇为什么这不起作用,点赞或分享这个问题,让我们都能发现,干杯!
将事件发射器从路由处理程序中拉出。每次运行路由处理程序时,都会为'addPictureToObjects'
添加另一个事件处理程序。您确实希望在每个请求上发出该事件,但不希望在每个申请上只注册一次事件处理程序。
您得到错误"Can't set headers after they are sent."
,因为第一个事件处理程序运行,迭代list
中的所有项,然后调用res.json
,后者将响应发送回客户端。但是,由于您为每个请求注册了多个事件处理程序,它会运行该代码两次(或三次,或四次,等等,取决于您每次到达该路由并注册新事件处理程序的次数(。在该代码的后续运行中,当它第二次到达res.json
时,它会出错,说它不能再修改响应了,因为它已经被发送回客户端。
// gets photos for each user in the 'list'
eventEmitter.on('addPictureToObjects', function(list, res) {
list.forEach(function(listItem, i) {
User.findOne({_id: listItem.id}, 'photo', function(err, guest) {
listItem.photo = guest.photo;
// if this is the last one send json object back
if (i+1 == list.length) {
res.json({list: list});
}
});
});
});
// loads people user has chatted with
router.get('/loadUserChats', function(req, res) {
var hostID = req.query.id;
let list = [];
let readyToSend = true;
// get the user
User.findOne({_id: hostID}, function(err, user) {
// checks if user has chatted at all
if (user.chat) {
// loops through the chat
user.chat.forEach(function(chat) {
var photoURL = "";
console.log(chat.user);
// push the chat info so later we can load messages
// by its ID
list.push({
id: chat.user.id,
name: chat.user.name
});
});
// okay, now that we are done looping lets add photos
// to each one of those so it looks better
eventEmitter.emit('addPictureToObjects', list, res);
}
});
});
您也可以将eventEmitter.on
更改为eventEmitter.once
,这样也可以解决您的问题。.once
注册事件处理程序,但在事件处理程序运行后取消注册。然而,在您的代码中,这似乎毫无意义,因为似乎没有理由在每个请求中反复注册处理程序和注销它,因此在请求处理程序之外注册事件处理程序似乎是理想的解决方案。
这不是你真正的问题,但这里不需要事件发射器。它仍然在执行第一个db请求,然后在该请求的回调中发出事件来执行第二个请求。它仍然在做一个请求,然后再做另一个请求。事件发射器没有改变这一点。以下代码与上述代码等效:
// loads people user has chatted with
router.get('/loadUserChats', function(req, res) {
var hostID = req.query.id;
let list = [];
let readyToSend = true;
// get the user
User.findOne({_id: hostID}, function(err, user) {
// checks if user has chatted at all
if (user.chat) {
// loops through the chat
user.chat.forEach(function(chat) {
var photoURL = "";
console.log(chat.user);
// push the chat info so later we can load messages
// by its ID
list.push({
id: chat.user.id,
name: chat.user.name
});
});
// okay, now that we are done looping lets add photos
// to each one of those so it looks better
list.forEach(function(listItem, i) {
User.findOne({_id: listItem.id}, 'photo', function(err, guest) {
listItem.photo = guest.photo;
// if this is the last one send json object back
if (i+1 == list.length) {
res.json({list: list});
}
});
});
}
});
});
- nodejs-expressjs上传图像并显示它们
- TypeError:在不兼容的接收器nodejs上调用了方法Uint8Array.length
- NodeJS-readline暂停和恢复事件发射器(逐行读取)
- NodeJS日期格式不起作用
- Nested Q.all nodejs
- Nodejs API控制器,用于在API之间切换
- 否'访问控制允许来源'标头存在于IISNOde中请求的资源(AngularJS+NodeJs)上
- 如何在大型nodeJS代码的基础上逐步引入typescript
- 在Nodejs中Express输入DEBUG=app时权限被拒绝/bin
- 无法使用nodeJS在html中设置Image src
- 与域在同一台计算机上运行的NODEJS服务器的CORS错误
- NodeJS API调用中Array中的Push和Pull元素
- 基于api密钥的NodeJS web服务
- 在gump和nodejs中使用Typescript时,未定义对require和exports的引用
- “util.inherits”和在NodeJS中扩展原型之间的区别
- 将一个方法转换为promise:Nodejs
- nodejs中匿名函数的使用
- Nodejs Express 4 Routing Questin
- nodejs expressjs angularjs routing
- NodeJS routing -