2016-06-21 61 views
3

我得到尝试使用MEAN堆栈进行异步查询时,回调已被称为错误。我需要第二个回调才能在嵌套查询完成后触发(按照代码中的注释)。为什么我得到这个错误?路线尝试进行嵌套查询时,已经调用了节点异步回调

例子:

router.route('/teams/:user_id').get(function (req, res) { 

TeamProfile.find({ 
    Members : { 
     $in : [req.params.user_id] 
    } 
}).exec(function (err, teamProfiles) { 

    var asyncTasks = []; 

    teamProfiles.forEach(function (teamProfile) { 
     asyncTasks.push(function (callback) { 
      UserProfile.find({ 
       UserID : { 
        $in : teamProfile.Members.map(function (id) { 
         return id; 
        }) 
       } 
      }, function (err, userProfiles) { 
       teamProfile.Members = userProfiles; 
       callback(); 
      }) 
     }); 
    }); 

    teamProfiles.forEach(function (teamProfile) { 
     asyncTasks.push(function (callback) { 
      Draft.find({ 
       _id : { 
        $in : teamProfile.Drafts.map(function (id) { 
         return id; 
        }) 
       } 
      }, function (err, drafts) { 
       teamProfile.Drafts = drafts; 

       drafts.forEach(function (draft) { 
        Comment.find({ 
         _id : { 
          $in : draft.Comments.map(function (id) { 
           return id; 
          }) 
         } 
        }).exec(function (err, comments) { 
         draft.Comments = comments; 
         callback(); 
         //This is where the callback should be called 
         //Throws Error: Callback was already called. 
        })      
       }) 

      }) 
     }); 
    }); 

    async.parallel(asyncTasks, function() { 
     res.json(teamProfiles) 
    }); 
}); 
}) 

我使用async.parallel()执行所有的查询。所有这些我都很新,所以请原谅一些初学者的错误。

回答

3

您正在同步迭代drafts并在第一项上调用异步的callback函数。当您尝试再次调用第二个项目时出现错误是预期的行为。

您应该在完成所有草稿查询后调用done回调,而不是每个查询。由于您使用的是异步,因此您可以嵌套另一个async.each来处理此问题:

router.route('/teams/:user_id').get(function (req, res) { 

     TeamProfile.find({ 
      Members : { 
       $in : [req.params.user_id] 
      } 
     }).exec(function (err, teamProfiles) { 

      var asyncTasks = []; 

      teamProfiles.forEach(function (teamProfile) { 

       asyncTasks.push(function (callback) { 
        UserProfile.find({ 
         UserID : { 
          $in : teamProfile.Members.map(function (id) { 
           return id; 
          }) 
         } 
        }, function (err, userProfiles) { 
         teamProfile.Members = userProfiles; 
         callback(); 
        }); 
       }); 
      }); 

      teamProfiles.forEach(function (teamProfile) { 
       asyncTasks.push(function (callback) { 
        Draft.find({ 
         _id : { 
          $in : teamProfile.Drafts.map(function (id) { 
           return id; 
          }) 
         } 
        }, function (err, drafts) { 
         teamProfile.Drafts = drafts; 

         async.each(drafts, function(draft, draftCallback){ 

          Comment.find({ 
           _id : { 
            $in : draft.Comments.map(function (id) { 
             return id; 
            }) 
           } 
          }).exec(function (err, comments) { 
           draft.Comments = comments; 
           draftCallback(); 
          }); 

         }, function(err){ 
          callback(); 
         }); 
        }); 
       }); 
      }); 

      async.parallel(asyncTasks, function() { 
       res.json(teamProfiles) 
      }); 
     }); 
    }); 
+0

感谢您的解释和解答。它完美的作品:) – Poot87

+0

很高兴帮助:) – cviejo