推送后数组保持为空
Posted
技术标签:
【中文标题】推送后数组保持为空【英文标题】:Array remains empty after push 【发布时间】:2019-06-13 13:33:09 【问题描述】:我声明了一个数组,但是当我将元素推入其中时,它仍然是空的。这是我的代码:
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',
]
);
这是 Recipecat 架构:
var recipecatSchema = new Schema(
name:
type: String,
required: true
);
我想用他们的名字替换 recipeCats 的 objectIds。
当我记录“catsObjectId”时,它显示一个空数组。
似乎是什么问题?
提前致谢!
【问题讨论】:
.find()
和 .findOne()
是异步的
@Andreas 我应该如何编写代码?
【参考方案1】:
(我知道这个问题有点老了,但如果您仍然需要帮助)
那是因为您正在推送到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
。但是console.log(catsObjectId)
已经被执行,而catsObjectId
在执行时是空的。
您应该在回调.then((data) => // use data here)
中使用catsObjectId
或使用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()
【讨论】:
【参考方案2】:您必须使用 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);
);
【讨论】:
没用,还是空的! 每次推送后尝试“console.log”查看发生了什么。例如试试这个:catsObjectId.push(item);控制台.log(项目); console.log(catsObjectId); 'console.log' 推送后工作正常,但外面显示为空。【参考方案3】:每次通过 for 循环时都会推送一个空数组。尝试删除此行。
catsObjectId.push([]);
【讨论】:
没用,还是空的!以上是关于推送后数组保持为空的主要内容,如果未能解决你的问题,请参考以下文章