等待异步任务完成nodejs

时间:2016-09-11 12:01:54

标签: node.js asynchronous sails.js sails-mongo

我正在创建一个应用程序,用户可以拥有多个房间,每个房间可以有多个频道,这是检索房间和相应频道时的代码:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

               var roomsObj = {};
               var roomsArr = [];//we will place the roomsObj inside the roomsArr

               var chansObj = {};
               var chansArr = [];

               async.each(rooms, function (roomId, cb){
                    roomsObj = {};
                   if (roomId !== '') {
                    Rooms.findOne({id: roomId}).exec(function (err, room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;

                        var channels = room.channels;
                        async.each(channels, function (channelId, cb) {
                             chansObj = {};
                            Channels.findOne({id: channelId}).exec(function (err, channel){
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            cb();
                       });
                        }, 
                        function (err) {

                        });


                    }); 
                }
                cb(); 

               }, function (err) {
                   roomsObj.channels = chansArr;
                    roomsArr.push(roomsObj);
                   sails.log(roomsArr);

               }); 



            });
        }

假设返回具有以下结构的javascript对象:

[ { name: "Room Name",
    roomId: "Room Id",
    inviteLink: "Room Invite Link",
    channels: [
                {
                 name: "Channel Name",
                 id: "channel Id"
                 }
               ]
   }

]

但是我总是得到一个空数组,因为async.each(rooms, function (roomId, cb){ })不等待async.each(channels, function (channelId, cb) {})完成,所以我有空房间对象。请问我该如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

完成rooms's callback循环后,您应该调用channels循环。

你应该这样做:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

               var roomsObj = {};
               var roomsArr = [];//we will place the roomsObj inside the roomsArr

               var chansObj = {};
               var chansArr = [];

               async.each(rooms, function (roomId, callback1){
                    roomsObj = {};
                   if (roomId !== '') {
                    Rooms.findOne({id: roomId}).exec(function (err, room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;

                        var channels = room.channels;
                        var i=0;
                        async.each(channels, function (channelId, callback2) {
                             chansObj = {};
                            Channels.findOne({id: channelId}).exec(function (err, channel){
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            i++;
                            if(i===(channels.length-1)){
                              i=0;
                               callback1(); 
                            }else{
                            callback2();
                            }
                       });
                        }, 
                        function (err) {
                        });
                    }); 
                }

               }, function (err) {
                   roomsObj.channels = chansArr;
                    roomsArr.push(roomsObj);
                   sails.log(roomsArr);
               }); 
            });
        }

答案 1 :(得分:0)

我解决了它,它确实是一个承诺的情况,我使用bluebird promise与async结合 - 修改后的代码:

getRooms: function (req, res) {
            User.find({id: req.cookies.claver_id}).exec(function (err, result) {
               if (err) {
                  return res.send(400);
               }
               rooms = result[0].rooms;
               if (rooms.length === 1) {//No room defaults to ['']
                   return res.send(400);
               }

                var roomsObj = {};
                var roomsArr = [];//we will place the roomsObj inside the roomsArr

                var chansObj = {};
                var chansArr = [];
               Promise.each(rooms, function (roomId, callback1){
                    roomsObj = {};
                   if (roomId !== '') {
                    async.series ([
                      function () {
                          Rooms.findOne({id: roomId}).then(function (room){
                        roomName = room.name; 
                        inviteLink = room.inviteLink;
                        roomsObj.name = roomName;
                        roomsObj.id = roomId;
                        roomsObj.inviteLink = inviteLink;
                         channels = room.channels;
                         sails.log(roomName);
                         })
                     }
                     ]);
                      return   Promise.each(channels, function (channelId) {
                           return Promise.all([
                             Channels.findOne({id: channelId}).then(function (channel){
                            chansObj = {};
                            chansObj.name = channel.channelName;
                            chansObj.id = channelId;
                            chansObj.type = channel.channelType;
                            chansArr.push(chansObj);
                            sails.log(chansObj);
                          })
                           ]).then(function () {
                               sails.log('done one');

                           });
                        }).then(function () {
                             roomsObj.channels = chansArr; 
                             roomsArr.push(roomsObj);
                            sails.log('done all');
                            chansArr = [];

                        });
              }
               }).then(function () {
                        sails.log(roomsArr);
                        sails.log("grand finish");
                    });

            });
        }

感谢所有贡献的人。