1

我最近在猫鼬中偶然发现了一个问题,这是我的代码:

var v, query;
for(var i=0; i<values.length; i++) {
    v = values[i];
    query = model.findOne({type:v});
    query.exec(function(err, doc) {
      if(doc == undefined) {
        var m = new model({type:v, count:0});
        // but the 'v' above is not the values[i] in the for loop
        // code to save comes here
      } else {
        doc.count++;
        // update code comes here
      }
    });
}

我想检查 doc 是否为空,如果是,则在数据库中输入一个默认值。如果返回了文档,则更新它的属性。问题是我试图保存的对象有 values[i] 作为它的属性之一。但是因为它是一个回调,所以我没有得到那个特定的值,因为它在 for 循环中继续进行。

我通过在模型创建过程中为所有不同的值插入一个默认对象来解决这个问题,但是在代码流的这一点上有没有办法做到这一点?

4

1 回答 1

2

试试这个:

values.forEach(function(v) {
  var query = model.findOne({type:v});
  query.exec(function(err, doc) {
    if(doc == undefined) {
      var m = new model({type:v, count:0});
      // but the 'v' above is not the values[i] in the for loop
      // code to save comes here
    } else {
      doc.count++;
      // update code comes here
    }
  });
});

它不适用于for循环的原因是因为 Javascript 没有块范围,这意味着v块中引用的变量被重用而不是重新创建。

当您立即使用该变量时(就像model.findOne({ type: v})这不是问题一样,但是由于 for 的回调函数query.exec将(可能)在循环完成后执行,v因此回调中的变量将仅包含循环中的最后一个值v

通过使用forEach,您每次都会创建一个新变量。v

于 2013-03-31T11:54:01.017 回答