如何强制javascript不使回调函数并行?

如何强制javascript不使回调函数并行?,javascript,node.js,callback,mongoose,Javascript,Node.js,Callback,Mongoose,我正在使用Node.js和MongoDB与mongoose构建一个twitter克隆。我的Tweet模型有body、user和created字段,其中user是创建Tweet的用户的id。现在我正在构建API。我希望在发出GET请求时接收所有推文的列表(/api/tweets/),但除了用户字段(仅返回用户id)之外,我希望获得整个用户对象,以便在前端部分显示推文所有者的信息。我最终得到了以下代码 exports.all = function (req, res, next) { Tweet

我正在使用Node.js和MongoDB与mongoose构建一个twitter克隆。我的
Tweet
模型有
body
user
created
字段,其中
user
是创建Tweet的用户的id。现在我正在构建API。我希望在发出GET请求时接收所有推文的列表(
/api/tweets/
),但除了
用户
字段(仅返回用户id)之外,我希望获得整个用户对象,以便在前端部分显示推文所有者的信息。我最终得到了以下代码

exports.all = function (req, res, next) {
  Tweet.find({}, function (err, tweets) {
    if (err) return res.json(400, err);

    var response = [];
    tweets.forEach(function (element, index, array) {
      var tweet = {};
      tweet._id = element._id;
      tweet.created = element.created;
      tweet.body = element.body;
      User.findById(element.user, function (err, user) { // <- This line
        if (err) return res.json(400, err);

        tweet.user = user;
      });

      response.push(tweet);
    });

    return res.json(response);
  });
};
exports.all=函数(req、res、next){
find({},函数(err,tweets){
if(err)返回res.json(400,err);
var响应=[];
forEach(函数(元素、索引、数组){
var tweet={};
tweet.\u id=element.\u id;
tweet.created=element.created;
tweet.body=element.body;

User.findById(element.User,function(err,User){/问题是
res.json
发送响应,因此调用
findById
并不重要。一旦一切完成,您需要调用
res.json

您可以通过多种方式实现这一点,但使用现有代码最简单的方法是只保留一个计数器:

var tweetCount = 0;

tweets.forEach(/* snip */) {
    User.findById(element.user, function (err, user) {
        tweet.user = user;
        tweetCount++;
        response.push(tweet);

        if (tweetCount == tweets.length) {
            res.json(response);
        }
    });
});

你会想使用图书馆,它会让你的生活更轻松

// inside `Tweet.find`
async.each(tweets, function(done) {
    // do stuff to tweets
    User.findById(element.user, function(err, user){
        if (err) return done(err);
        // do stuff with user
        done();
    });
}, function(err) {
   // called when done
   res.json(response);
});
您可以使用Qpromise库来同步。它简单易用

只有当整个承诺链完成时,才会发送响应

var result = Q();
tweets.forEach(function (tweet, i) {
     result = result.then(function () {
         // do your stuff
     }

result.then(function () {
    res.json(response);  //successfully completed
});

异步API不能同步。我也强烈建议使用此路由。仅在某些情况下需要使用异步,而无需链接回调负载。