var access error inside findOne in forEach nodejs

var access error inside findOne in forEach nodejs

本文关键字:in forEach nodejs findOne inside access error var      更新时间:2023-09-26
 api.get('/evaluateproductratings', function(req, res){
    Product.find({}, function(err, results){
      results.forEach(function(product){
          var rate = math.divide(0.0,1);
          var count = math.add(0,0);
          product.Ingredients.split(", ").forEach(function(ingredient){
            Ingredient.findOne({title: ingredient}, function(err, ing){
              if(err) {
                console.log(err);
              }
              else if(!ing){
                rate = math.add(rate, 0.0);
                count = math.add(count, 1);
              }
              else{
                  rate = math.add(rate, ing.Weightage);
                  count = math.add(count, 1);          
              }
            })
          })   
          var finalrate = math.divide(rate,count);
          console.log(finalrate);
          product.update({$set:{'Rating': finalrate}}, function(err, result){
            if(err){
              console.log(err);
            }
            else{
              console.log('product rated successfully.');
            }
          })
        })
        res.json('all products rated successfully');
    })
})        

这里发生的问题是我无法更新 Ingredient.findOne 中的变量 rate 和计数,因此 finalrate 始终评估为 NaN(即 0/0),因为每个产品的速率和计数都初始化为 0。

产品架构 :

 title:"something",
 Ingredient:"ing1, ing2, ing3"

成分模式 :

 title:"ing1",
 Weightage:"2"
 title:"ing2",
 Weightage:"5"
 title:"ing3",
 Weightage:"7"

如何解决这个问题?

您需要

将更新函数移动到Ingredient.findOne()回调中,否则您的速率和计数值将不会更新为新值。您的更新函数在Ingredient.findOne()回调之外,这意味着您的Ingredient.findOne()product.update()在流中的同一点执行,在这种情况下,您的更新语句永远无法知道您的速率和计数更新到什么。

api.get('/evaluateproductratings', function(req, res){
    Product.find({}, function(err, results){
      results.forEach(function(product){
          var rate = math.divide(0.0,1);
          var count = math.add(0,0);
          product.Ingredients.split(", ").forEach(function(ingredient){
            Ingredient.findOne({title: ingredient}, function(err, ing){
              if(err) {
                console.log(err);
              }
              else if(!ing){
                rate = math.add(rate, 0.0);
                count = math.add(count, 1);
              }
              else{
                  rate = math.add(rate, ing.Weightage);
                  count = math.add(count, 1);          
              }
              var finalrate = math.divide(rate,count);
              console.log(finalrate);
              product.update({$set:{'Rating': finalrate}}, function(err, result){
                if(err){
                  console.log(err);
                }
                else{
                  console.log('product rated successfully.');
                  return res.json('all products rated successfully');
                }
              });
            });
          });
        });
    });
});