Как передать переменную в обратный вызов mongodb?

Я пытаюсь выбрать разные значения для двух полей из моего mongodb. Используя async.series, у меня есть следующее:

function getSettings(target){
    var versions = [];
    var result = {};

    function putResults(key, val){
        result[key] = val;
    }
  async.series(
  [
    function(callback){
        db.get(target).distinct('version', function(err, arr){
            if(err) return err;
            versions = arr;
            callback();
        }); //end db call
    },
    function(callback){
        var items;
        for(var i = 0; i<versions.length; i++)
        {
            db.get(target).distinct('instance', {version: versions[i]}, function(err, arr){
                items = arr;
                putResults(versions[i], items);
            }); //end db call
         }
     }
  ], 
  function(err){
         if(err) return err;
         console.log(result);
  }); //end async
}

С помощью этого кода я получаю "неопределенное" исключение для putResults(версии [i], элементы). Я знаю, это потому, что версии выходят за рамки. Мой вопрос: как я могу получить его в объеме?

Ожидаемый результат:

 result = {1: [1, 2, 3], 2: [1, 2, 3, 4]}

2 ответа

Решение

В нашем случае лучше использовать водопад вместо seriesи карта, вот так

function getSettings(target){
  async.waterfall([
    function (callback) {
      db.get(target).distinct('version', function (err, versions) {
         callback(err, versions);
      });
    },
    function (versions, callback) {
      async.map(versions, function (version, next) {
        db.get(target).distinct('instance', {version: version}, function (err, items) {
          var result = {};
          result[version] = items;
          next(err, result);
        });
      }, function (err, res) {
        callback(err, res);
      });
    }
  ], function (err, result) {
    if (err) {
      return;
    } 

    console.log(result);
  });
}

Как отметил Александр в своем комментарии, если вы хотите передать значения из первой функции в следующую, вы должны использовать waterfall вместо series,

Как указано в официальной документации относительно waterfall:

Запускает массив задач последовательно, каждая из которых передает свои результаты следующему в массиве. Однако, если какая-либо из задач передает ошибку своему собственному обратному вызову, следующая функция не выполняется, и основной обратный вызов немедленно вызывается с ошибкой.

Если вы хотите узнать больше о различных возможностях асинхронного подключения, я настоятельно рекомендую их официальную документацию ( ССЫЛКА).

Другие вопросы по тегам