繁体   English   中英

通过 mongoose 访问数组元素

[英]Access array elements via 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

然后函数崩溃了

TypeError: Cannot read property 'product' of undefined

在线

debug("Product is %s", request.requests[i].product);

此函数的目标是验证一个请求(我们将其状态从“待处理”变为“已接受”)。 但是当我们这样做时,仓库中的库存需要减少(“数量”参数)。 我们无法访问 product 属性似乎很合乎逻辑,因为i的值为2并且我们的数组中没有第三个元素。 但是为什么我的迭代变量超出了它的范围? 我该如何解决? 控制台只打印一次“Inside”这一事实让我怀疑这是否不是另一个异步问题。

这是关于异步执行代码的问题。 特别是 for 循环“触发”多个异步函数和连续执行。 在循环完你的循环i===2 当第一个Material.findOne回调被执行时requests[2] === undefined (as 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 模块,具有许多功能来处理异步编程的执行和控制流。

暂无
暂无

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

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