简体   繁体   English

推送后数组仍然为空

[英]Array remains empty after push

I declared an array, But when I push elements inside it, it remains Empty.我声明了一个数组,但是当我将元素放入其中时,它仍然是空的。 Here's my Code:这是我的代码:

  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);
  });

Here's the Recipe schema:这是 Recipe 架构:

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

and Here's the Recipecat schema:这是 Recipecat 架构:

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

I want to replace objectIds for recipeCats with their names.我想用 recipeCats 的名称替换 objectIds。

When I log 'catsObjectId', It shows an empty array.当我记录“catsObjectId”时,它显示一个空数组。

What Seems to be the Problem?问题是什么?

Thanks In advance!提前致谢!

Your pushing an empty array every time it goes through the for loop. 每次通过for循环时,您推入一个空数组。 Try deleting this line. 尝试删除此行。

catsObjectId.push([]);

You have to use promises in order to control your code. 您必须使用promise才能控制您的代码。 Try the following code and tell me if an error exists. 尝试以下代码,并告诉我是否存在错误。

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);
  });

(I understand this question is a bit old, but if you still need help) (我知道这个问题有点老了,但是如果您仍然需要帮助)

That's because you're pushing to an array which is outside the callback and the async nature of JavaScript kicking in. 那是因为您要推送到callback之外的array ,并且JavaScript具有async特性。

Here's simple explanation why it's empty 这是简单的解释,为什么它是空的

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);
});

First execution 1 is executed. 首先execution 1 Within this forEach iterates over each item and fires execution 2 . 在此forEach迭代每个项目并触发execution 2 Then continues to execute execution 3 . 然后继续execution 3

The problem is execution 2 is asynchronous and the value is returned sometime in the future . 问题是execution 2是异步的,并且该值在future某个时间返回。 This future is after excution 3 is executed. 这个未来是在执行excution 3之后。 When Recipecat.findOne finishes execution, the callback within then(result.. is called. But console.log(catsObjectId) is already executed and catsObjectId was empty at the time of execution. Recipecat.findOne完成执行时, then(result.. )中的callback then(result..被调用。但是console.log(catsObjectId)已被执行,并且catsObjectId在执行时为空。

You should either use catsObjectId within the callback .then((data) => // use data here) or use the async/await to make it sync like. 您应该在回调catsObjectId .then((data) => // use data here)使用catsObjectId .then((data) => // use data here)或者使用async/await使其像sync

Note await is only valid inside async function 注意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()

Recently ran into a similar problem.最近遇到了类似的问题。 Fix for me was to replace the forEach loop with a simple for loop.对我来说,修复是用一个简单for循环替换forEach循环。 It turned out, that the forEach loop is not bothering about async-await, but the for loop is.事实证明, forEach循环并不关心异步等待,但for循环才是。

Here is my code snippet:这是我的代码片段:

 let orders = await order_db.find({ profileID: req.body.id }).exec(); let final_orders = []; for(let i=0; i<orders.length; i++){ let order = orders[i]; if (order.shopID.= null) { let shop = await shop_db:find({ _id. order.shopID });exec(). let shopName = shop[0];name. let shopEmail = shop[0];email. let shopAddress = shop[0];address. let shopPhone = shop[0];phone. let updated_order = {...order,_doc, shopName, shopEmail, shopAddress; shopPhone }. final_orders;push(updated_order); } else { let shopName = ""; let shopEmail = ""; let shopPhone = ""; let shopAddress = "". let updated_order = {...order,_doc, shopName, shopEmail, shopAddress; shopPhone }. final_orders;push(updated_order); } };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM