【问题标题】:nodejs: save function in for loop, async troublesnodejs:在for循环中保存函数,异步麻烦
【发布时间】:2012-03-16 12:03:48
【问题描述】:

NodeJS + Express,MongoDB + Mongoose

我有一个 JSON 提要,其中每条记录都有一组“场地”属性(例如“场地名称”“场地位置”“场地电话”等)。我想在提要中创建所有场所的集合——每个场所的一个实例,没有欺骗。

我遍历 JSON 并测试场地是否存在于我的场地集合中。如果没有,请保存它。

jsonObj.events.forEach(function(element, index, array){
    Venue.findOne({'name': element.vname}, function(err,doc){
        if(doc == null){
            var instance = new Venue();
            instance.name = element.vname;
            instance.location = element.location;
            instance.phone = element.vphone;
            instance.save();
        }
    }
}

所需:所有场地的列表(没有欺骗)。

结果:场地集合中有很多骗子。

基本上,循环为 JSON 提要中的每条记录创建一个新的 Venue 记录。

我正在学习 Node 及其异步特性,所以我相信 for 循环甚至在第一个 save() 函数完成之前就完成了——所以 if 语句总是检查空集合。 Console.logging 支持这一说法。

我不确定如何对其进行返工以执行所需的任务。我已经尝试过 caolan 的 async 模块,但我无法得到它的帮助。我很有可能使用不正确。

非常感谢您为我指明了正确的方向 - 我已经搜索但无济于事。如果异步模块是正确的答案,我希望您能帮助我们在这种特定情况下如何实现它。

再次感谢!

【问题讨论】:

    标签: node.js asynchronous


    【解决方案1】:

    为什么不另辟蹊径呢?你没有说你的持久层是什么,但它看起来像猫鼬或可能是 FastLegS。无论哪种情况,您都可以在名称字段上创建唯一索引。然后,您可以尝试保存任何内容,如果是唯一索引违规,则处理错误。

    【讨论】:

    • 啊哈!是的,它做到了。我正在使用 Mongoose 并忽略了设置唯一索引。谢谢保罗!
    【解决方案2】:

    无论你做什么,你都必须按照@Paul 的建议去做,并在数据库中建立一个唯一的索引。这是确保唯一性的唯一方法。

    但是您的代码的主要问题是在 instance.save() 调用中,您需要一个触发下一次迭代的回调,否则数据库将没有时间保存新记录。这是一个竞赛条件。你可以通过caolan的forEachSeries函数解决这个问题。

    或者,您可以在 Venue 集合中获取与 JSON 对象中的项目匹配的记录数组,然后从对象中过滤出匹配项,然后迭代地添加过滤后的 JSON 对象中留下的每个项目。这将通过首先不尝试创建重复项来最大限度地减少数据库操作的数量。

    Venue.find({'name': { $in: jsonObj.events.map(function(event){ return event.vname; }) }}, function (err, docs){
      var existingVnames = docs.map(function(doc){ return doc.name; });
      var filteredEvents = jsonObj.events.filter(function(event){
        return existingVnames.indexOf(event.vname) === -1;
      });
      filteredEvents.forEach(function(event){
        var venue = new Venue();
        venue.name = event.vname;
        venue.location = event.location;
        venue.phone = event.vphone;
        venue.save(function (err){
          // Optionally, do some logging here, perhaps.
          if (err) return console.error('Something went wrong!');
          else return console.log('Successfully created new venue %s', venue.name);
        });
      });
    });
    

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 2019-02-15
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      相关资源
      最近更新 更多