繁体   English   中英

推送后数组仍然为空

[英]Array remains empty after push

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

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

这是 Recipe 架构:

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

这是 Recipecat 架构:

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

我想用 recipeCats 的名称替换 objectIds。

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

问题是什么?

提前致谢!

每次通过for循环时,您推入一个空数组。 尝试删除此行。

catsObjectId.push([]);

您必须使用promise才能控制您的代码。 尝试以下代码,并告诉我是否存在错误。

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

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

那是因为您要推送到callback之外的array ,并且JavaScript具有async特性。

这是简单的解释,为什么它是空的

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完成执行时, then(result.. )中的callback then(result..被调用。但是console.log(catsObjectId)已被执行,并且catsObjectId在执行时为空。

您应该在回调catsObjectId .then((data) => // use data here)使用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()

最近遇到了类似的问题。 对我来说,修复是用一个简单for循环替换forEach循环。 事实证明, forEach循环并不关心异步等待,但for循环才是。

这是我的代码片段:

 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