Node.js 带有NodeJS和Async的forEach

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(

我是新来的NodeJS(快车)。我正在尝试构建一个API,该API将列出酒店的“房间”以及每个房间的“照片”

我想做的是: -获取酒店所有房间的列表 -循环浏览此房间列表并添加照片 -返回带有房间和照片的JSON

我的问题是,我似乎无法将“照片”结果附加到“房间”结果

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