Nodejs for-loops并等到循环结束

时间:2014-05-29 14:13:36

标签: javascript node.js mongoose

我有以下代码:

    //Marks all users which are reading the book with the bookId
 var markAsReading = function (bookId,cb) {
    User.find({}, function (err,users) {
        if(err)
            cb(err);
        //Go through all users with lodash each function
        _(users).each(function (user) {
            //Go through all books
            _(user.books).each(function (book) {

                if(book.matchId === bookId)
                {
                    user.isReading = true;
                    //cb();
                }
            });
        });
        //Need to callback here!!#1 cb(); -->Not working!
    });
       //Or better here! cb() --> Not working
};
exports.markAsReading = markAsReading;

我正在使用带有mongoose和mongodb的nodejs。 我想做什么:

  1. 使用mongoose从mongodb获取所有用户
  2. 在lodash的帮助下,每个功能遍历所有用户
  3. 在每个用户上浏览用户书籍(也包括lodash和每个用户)
  4. 如果当前bookId与函数参数中的bookId匹配 - >设置书籍“isReading”属性 - >真
  5. 我的问题是我只需要在位置#2完成所有内容时回调 但是整个User.find及其嵌套的回调都没有准备好!

    如果所有循环和find方法都准备就绪,我如何解决这个问题呢?

    我已经阅读了有关promises和async lib的内容,但我如何在这种情况下使用它?

    最诚挚的问候 迈克尔

2 个答案:

答案 0 :(得分:5)

我终于用这种模式的异步库解决了这个问题:

async.forEach(list,function (item,callback) {
              //do something with the item
              callback();//Callback when 1 item is finished
           }, function () {
               //This function is called when the whole forEach loop is over
               cb() //--> This is the point where i call the callback because the iteration is over
           });

答案 1 :(得分:0)

您可以使用来自灵活http://caolan.github.io/nimble/

的每个循环进行同步
var nimble = require('nimble');

var markAsReading = function (bookId,cb) {
    User.find({}, function (err,users) {
        if(err)
            cb(err);

        nimble.each(users, function (user) {
             nimble.each(user.books, function (book) {
                if(book.matchId === bookId)
                {
                    user.isReading = true;
                }
            });
        });
        cb(null);
    });
};