Массив остается пустым после нажатия - PullRequest
0 голосов
/ 19 января 2019

Я объявил массив, но когда я помещаю в него элементы, он остается пустым.Вот мой код:

  var catsObjectId = new Array();
  var data = new Array();
  Recipe.find((err,doc3)=> {
    data = doc3;
    for (var i = 0; i < data.length; i++) {
      catsObjectId.push([]);
      data[i]['categories'].forEach((item, index) => {
        Recipecat.findOne({_id: item}, (err,result)=> {
          item = result.name;
          catsObjectId.push(item);
        });
      })
    }
    console.log(catsObjectId);
  });

Вот схема рецепта:

var recipeSchema = Schema({
  categories: [{
    type: Schema.Types.ObjectId,
    ref: 'RecipeCat',
  }]
});

и вот схема рецепта:

var recipecatSchema = new Schema({
    name: {
        type: String,
        required: true
    }
});

Я хочу заменить objectIds для recipeCats их именами.

Когда я регистрирую 'catsObjectId', отображается пустой массив.

В чем проблема?

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 19 января 2019

Вы должны использовать обещания, чтобы контролировать свой код. Попробуйте следующий код и сообщите мне, если существует ошибка.

Recipe.find().then(doc3 => {
    data = doc3;
    for (var i = 0; i < data.length; i++) {
      data[i]['categories'].forEach((item, index) => {
        Recipecat.findOne({_id: item}).then(result => {
          item = result.name;
          catsObjectId.push(item);
        });
      })
    }
    console.log(catsObjectId);
  })
  .catch(err => {
      console.log(err);
  });
0 голосов
/ 11 апреля 2019

(я понимаю, что этот вопрос немного стар, но если вам все еще нужна помощь)

Это потому, что вы подталкиваете к array, который находится за пределами callback и async природыJavaScript вбрасывание.

Вот простое объяснение, почему оно пустое

var catsObjectId = new Array();
var data = new Array();

Recipe.find((err,doc3)=> {
  // say execution 1
  for (var i = 0; i < data.length; i++) {
    catsObjectId.push([]);
    data[i]['categories'].forEach((item, index) => {
      // say execution 2
      Recipecat.findOne({_id: item}, (err,result)=> {
        item = result.name;
        catsObjectId.push(item);
      });
    })
  }
  // say execution 3
  console.log(catsObjectId);
});

Сначала выполняется execution 1.В этом forEach перебирает каждый элемент и запускает execution 2.Затем продолжает выполнение execution 3.

Проблема в том, что execution 2 является асинхронным, и значение возвращается когда-то в future.Это будущее после excution 3.Когда Recipecat.findOne заканчивает выполнение, вызывается callback в пределах then(result...Но console.log(catsObjectId) уже выполнен и catsObjectId был пуст во время выполнения.

Вы должны либо использовать catsObjectId в обратном вызове .then((data) => // use data here), либо использовать async/await, чтобы сделать его syncкак.

Примечание await действует только внутри async функция

async function getSomeNames() {
  try {
    const data = await Recipe.find();
    // docs is an array of promises
    const docs = data.map((item, index) => {
      Recipecat.findOne({_id: item})
    });
    // items is an array of documents returned by findOne
    const items = await Promise.all(docs);
    // now you can map and get the names
    const names = items.map(item => item.name);
  } catch (e) {
    // handle error
    console.error(e);
  }
}
getSomeNames()
0 голосов
/ 19 января 2019

Вы отправляете пустой массив каждый раз, когда он проходит цикл for.Попробуйте удалить эту строку.

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