Добавление в массив асинхронно в Node.js - PullRequest
4 голосов
/ 04 октября 2011

Я довольно новичок в этом типе программирования, и у меня возникли некоторые проблемы с заполнением массива из вложенного вызова.Я почти уверен, что это должно быть сделано с помощью обратных вызовов, но у меня возникают проблемы с оборачиванием моего мозга вокруг этого.Закрытия должны также вступить в игру здесь.Я попытался найти в Интернете похожий пример, но ничего не нашел.

Вот мой оригинальный код.Я попробовал несколько разных подходов, но не справился.

TaskSchema.statics.formatAssignee = function(assignees) {
  var users = [];

  assignees.forEach(function(uid) {
    mongoose.model('User').findById(uid, function(err, user) {
      users.push({
          name: user.name.full
        , id: user.id
      });
    });
  });

  return users;
}

Ответы [ 3 ]

6 голосов
/ 05 октября 2011

Мне действительно нравится следующий шаблон (рекурсия - самое элегантное решение для асинхронных циклов):

TaskSchema.statics.formatAssignee = function(assignees, callback) {
  var acc = []
    , uids = assignees.slice()
  (function next(){
    if (!uids.length) return callback(null, acc);

    var uid = uids.pop()
    mongoose.model('User').findById(uid, function(err, user) {
      if (err) return callback(err);
      acc.push({
        name: user.name.full
      , id: user.id
      });
      next();
    });
  })();
}
2 голосов
/ 05 октября 2011

Check async , у него есть асинхронный цикл foreach.

Редактировать

Вот метод foreach из асинхронной библиотеки

async.forEach = function (arr, iterator, callback) {
    if (!arr.length) {
        return callback();
    }
    var completed = 0;
    _forEach(arr, function (x) {
        iterator(x, function (err) {
            if (err) {
                callback(err);
                callback = function () {};
            }
            else {
                completed += 1;
                if (completed === arr.length) {
                    callback();
                }
            }
        });
    });
};
var _forEach = function (arr, iterator) {
    if (arr.forEach) {
        return arr.forEach(iterator);
    }
    for (var i = 0; i < arr.length; i += 1) {
        iterator(arr[i], i, arr);
    }
};
0 голосов
/ 05 октября 2011

вы можете сделать что-то вроде:
Дать formatAssignee обратный вызов.
Отсчитать, сколько пользователей вам нужно отправить на пользователей.
После того, как вы нажмете последнего, вызовите обратный вызов с параметром users.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...