Node.js 带有NodeJS和Async的forEach
我是新来的NodeJS(快车)。我正在尝试构建一个API,该API将列出酒店的“房间”以及每个房间的“照片” 我想做的是: -获取酒店所有房间的列表 -循环浏览此房间列表并添加照片 -返回带有房间和照片的JSON 我的问题是,我似乎无法将“照片”结果附加到“房间”结果Node.js 带有NodeJS和Async的forEach,node.js,express,foreach,Node.js,Express,Foreach,我是新来的NodeJS(快车)。我正在尝试构建一个API,该API将列出酒店的“房间”以及每个房间的“照片” 我想做的是: -获取酒店所有房间的列表 -循环浏览此房间列表并添加照片 -返回带有房间和照片的JSON 我的问题是,我似乎无法将“照片”结果附加到“房间”结果 async.waterfall([ // Function 1 function(callback) { // Find all Hotel Rooms Room.find(
async.waterfall([
// Function 1
function(callback) {
// Find all Hotel Rooms
Room.find({ 'hotel': req.params.hotel_id})
.exec(function(err, rooms) {
callback(null, rooms); // Send rooms to function 2
});
},
// Function 2
function(rooms, callback) {
// Loop through each room to get photos for each room
rooms.forEach(function(room) {
// Get photos for room
RoomPhoto.find({ 'room': room._id})
.exec(function(err, photos) {
// I want to add these "photos" to the main "rooms" object, but attached to each individual "room"
room.photos = JSON.stringify(photos);
});
})
console.log(rooms)
callback(null, rooms);
}
], function(err, results) {
if(err) console.log('err');
res.json(results);
});
任何帮助都将不胜感激,因为我已经花了好几个小时试图解决这个问题
谢谢
射线
我已经更新了我的脚本,但是“照片”仍然没有进入最终的“房间”对象。我已经包括了代码和控制台输出 代码: 以下是上述脚本的控制台输出: 房间名称:1号试验室 房间名称:2号试验室 照片:
{ _id: 5acd3094e0026f38ca4b44bc,
src: 'https://picsum.photos/200/300/?image=252',
room: 5acd3094e0026f38ca4b44bb,
__v: 0 }
{ _id: 5acd30c8cec87777eefcd32d,
src: 'https://picsum.photos/200/300/?image=252',
room: 5acd30c8cec87777eefcd32c,
__v: 0 }
照片:
{ _id: 5acd3094e0026f38ca4b44bc,
src: 'https://picsum.photos/200/300/?image=252',
room: 5acd3094e0026f38ca4b44bb,
__v: 0 }
{ _id: 5acd30c8cec87777eefcd32d,
src: 'https://picsum.photos/200/300/?image=252',
room: 5acd30c8cec87777eefcd32c,
__v: 0 }
最终房间对象
[ { _id: 5acd3094e0026f38ca4b44bb,
name: 'Test Room 1',
hotel: 5accd4e1734d1d55c3195c84,
__v: 0 },
{ _id: 5acd30c8cec87777eefcd32c,
name: 'Test Room 2',
hotel: 5accd4e1734d1d55c3195c84,
__v: 0 } ]
尝试将第二个
回调(null,rooms);
行(靠近末尾的那一行)放在room.photos=JSON.stringify(photos);
行下面
由于JavaScript的异步特性,它可能在您的查询完成获取照片之前运行
如果房间没有照片,您可能还需要添加一些检查。由于函数
RoomPhoto
也是异步的,因此您需要等待所有照片加载后再调用回调函数。如下所示:
// Function 2
function(rooms, callback) {
// https://caolan.github.io/async/docs.html#each
// Loop through each room to get photos for each room
async.each(rooms, function(room, room_cb) {
// Get photos for room
RoomPhoto.find({ 'room': room._id})
.exec(function(err, photos) {
room.photos = JSON.stringify(photos)
room_cb()
});
}, function (err) {
console.log(rooms)
callback(null, rooms)
})
}
由于您不熟悉
node.js
,您可能不知道最新的标准和您可以使用的东西。以下是您如何在不包含async
模块的情况下完成此任务
const requestHandler = async (req, res, next) => {
let rooms = await Room.find({ 'hotel': req.params.hotel_id})
.exec()
.catch(err => {
console.log(err);
throw err;
});
// Get photos for room
let photos = await Promise.all(rooms.map(
room => RoomPhoto.find({ 'room': room._id})
.catch(err => {
console.log(err);
throw err;
});
))
rooms = rooms.map((room, index) => {
room = room.toObject();
room.photos = JSON.stringify(photos[index]);
return room;
});
// Now your "rooms" array will have room objects, with photos populated.
res.send(rooms);
});
要导出它,您可以这样做:
module.exports.index = requestHandler;
我发现了一些有用的东西。。。 出于某种原因,MongoDB“_id”导致了一个问题 exports.index=函数(req、res、next){
};你说的很有道理,但是当我运行脚本时,“照片”仍然没有附加到最后的“房间”object@RayPhelan尝试
async.eachOf
-rooms[key].photos=photos
…我刚刚尝试了async.eachOf…但照片仍然没有添加到“rooms”中“对象当我输出最终函数时,我认为这不是处理异步操作的问题。尝试在对MongoDB的请求中找出问题所在……MongoDB似乎确实存在问题,而不是异步问题。出于某种原因,mongodb的“_id”导致了一个问题,因为为了将“photos”添加到“room”,我需要先解析(rooms)JSON.parse,但是_id导致了一个错误。所以我使用了这个:rooms=JSON.parse(JSON.stringify(rooms.replace)(/\u id/g,“room\u id”);我试着复制这段代码,但它对medid无效。它会抛出任何错误吗?您是否完整地复制了它?您能否提及您的nodejs
版本和expressjs
版本这是错误消息,页面只是等待而不做任何事情:(节点:15404)未处理的Promisejection警告:未处理的承诺拒绝(拒绝id:1):类型错误:无法设置未定义的属性“照片”(节点:15404)[DEP0018]弃用警告:未处理的承诺拒绝将被弃用。将来,未处理的承诺拒绝将使用非零退出代码终止Node.js进程。Node v8.9.4,express 4.16.0