有了这份文件:
{
"_id" : 8,
"updatedAt" : ISODate("2016-04-13T05:07:38.905Z"),
"createdAt" : ISODate("2016-04-13T04:15:37.612Z"),
"author" : "test@test.com",
"urgency" : "slow",
"state" : "pending",
"comment" : "",
"requests" : [
{
"value" : 1,
"product" : "Slethoxynal",
"_id" : ObjectId("570dc7e91d15852f1c2ae66a")
},
{
"value" : 1,
"product" : "Thyrploxynénol",
"_id" : ObjectId("570dc7e91d15852f1c2ae66b")
}
],
"__v" : 0
}
我使用这个javascript函数:
function closeRequest(req, res, next) {
Request.findOne({ '_id': req.body.id}, function(err, request){
debug(request);
debug("Length is %s", request.requests.length);
for(var i=0;i<request.requests.length;i++){
debug("We validate the element %s of the request %s", i, req.body.id);
console.log(i);
Material.findOne({'title': request.requests[i].product}).exec(function(err, material){
debug("Inside i is : %i",i);
debug("Product is %s", request.requests[i].product);
debug("Material found is %s", material.title);
material.amount -= request.requests[i].value;
material.save(function(err) {
if(err)
res.send(err);
});
});
}
request.state='accepted';
request.save(function(err) {
if(err)
res.send(err);
});
});
res.redirect('back');
}
我的控制台打印出来:
0
1
Inside i is 2
然后该功能崩溃
TypeError: Cannot read property 'product' of undefined
在第
行debug("Product is %s", request.requests[i].product);
此功能的目标是验证一个请求(我们将其状态从&#39;等待&#39;接受&#39;接受&#39;)。但是,当我们这样做时,仓库中的库存需要递减(&#39;金额&#39;参数)。
我们无法访问产品属性似乎很合乎逻辑,因为i
的值为2
且数组中没有第三个元素。
但为什么我的迭代变量超出了它的范围?我怎么解决这个问题?控制台打印&#34; Inside&#34;只有一次让我想知道它是不是另一个异步问题。
答案 0 :(得分:1)
这是关于异步执行代码的问题。特别是for循环&#34;触发&#34;多个异步函数和连续执行。循环遍历循环i===2
之后。当第一个Material.findOne
回调被执行时requests[2] === undefined
(如requests.length === 2
)会引发您的错误。
我建议这样做:
var updateMaterialFns = request.requests.map(function(req, i) {
return function(done) {
debug("We validate the element %s of the request %s", i, req.body.id);
console.log(i);
Material.findOne({'title': req.product}).exec(function(err, material){
if (err) {
done(err)
}
debug("Inside i is : %i",i);
debug("Product is %s", request.requests[i].product);
debug("Material found is %s", material.title);
material.amount -= request.requests[i].value;
material.save(done)
})
}
})
async.parallel(updateMaterialFns, function(err) {
if (err) {
res.send(err)
}
})
async是一个node / npm模块,具有许多处理异步编程执行和控制流程的函数。