推送后数组仍为空

Ham*_*eri 6 javascript arrays node.js express

我声明了一个数组,但是当我将元素推入其中时,它仍然是空的。这是我的代码:

  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);
  });
Run Code Online (Sandbox Code Playgroud)

这是食谱架构:

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

这是 Recipecat 架构:

var recipecatSchema = new Schema({
    name: {
        type: String,
        required: true
    }
});
Run Code Online (Sandbox Code Playgroud)

我想用它们的名字替换recipeCats 的objectIds。

当我记录“catsObjectId”时,它显示一个空数组。

问题出在哪里?

提前致谢!

156*_*223 9

(我知道这个问题有点老了,但如果您仍然需要帮助)

那是因为你正在推动一个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);
});
Run Code Online (Sandbox Code Playgroud)

首先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()
Run Code Online (Sandbox Code Playgroud)


小智 0

每次通过 for 循环时都会推送一个空数组。尝试删除这一行。

catsObjectId.push([]);
Run Code Online (Sandbox Code Playgroud)