通过mongoose访问数组元素
有了这个文件:
{ "_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
然后function崩溃
TypeError: Cannot read property 'product' of undefined
在线
debug("Product is %s", request.requests[i].product);
这个函数的目标是validation一个请求(我们把它的状态从'pending'改为'accepted')。 但是,当我们这样做时,仓库中的库存需要减less(“数量”参数)。 看起来非常合乎逻辑,我们不能访问产品属性,因为i
有一个值为2
,没有第三个元素在我们的数组中。 但为什么我的迭代variables超出了它的范围? 我该如何解决? 控制台只打印一次“内部”的事实让我怀疑,这不是另一个asynchronous问题。
这是关于asynchronous执行代码的问题。 特别是for循环“触发”多个asynchronous函数和连续执行。 循环你的循环后i===2
。 由于第一个Material.findOne
callback得到执行requests[2] === undefined
(作为requests.length === 2
)抛出您的错误。
我会build议去这样的:
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) } })
asynchronous是一个节点/ npm模块,具有许多function来处理asynchronous编程的执行和控制stream程。