【问题标题】:Mongoose schema does not save inside async.forEach loopMongoose 模式不保存在 async.forEach 循环中
【发布时间】:2014-06-21 21:31:10
【问题描述】:

第一次发帖,如有错误请见谅……

我正在创建一些独立代码来读取文件夹结构并返回数组中的所有.mp3 文件。返回后,我将遍历数组,并为每个项目创建一个 Mongoose 对象并填充字段,然后使用 .save() 保存对象。

我正在使用 async.forEach 循环遍历数组 - 虽然它确实循环遍历了数组中的所有项目,但它们没有保存,并且没有产生任何错误来帮助我找出问题所在。

如果我将循环的逻辑移到其他地方,则 MP3 将存储在 mongodb 数据库中 - 如果我有显示的示例,则不会保存任何内容。

var saveMP3s = function(MP3Files, callback) {
  console.log('start loop -> saving MP3s');
  async.forEach( MP3Files, function(mp3file, callback) {
    newTrack = new MP3Track();
    newTrack.title = mp3file.title;
    newTrack.track = mp3file.track;
    newTrack.disk = mp3file.disk;
    newTrack.metadata = mp3file.metadata;
    newTrack.path = mp3file.path;
    console.log('....:> Song Start: ');
    console.log(newTrack.title);
    console.log(newTrack.track);
    console.log(newTrack.disk);
    console.log(newTrack.metadata);
    console.log(newTrack.path);
    console.log('....:> Song End: ');
    newTrack.save(function (err) {
      if (err) {
        console.log(err);
      } else {
        console.log('saving Track: '+ newTrack.title);
        callback();
      }
    });
  }, function(err) {
    if (err) { console.log(err); }
  });
  console.log('end loop -> finished saving MP3s');
};

我遇到的问题是,当代码不在异步循环中时,代码可以正常工作并且 MP3 保存在 MongoDB 数据库中,在异步代码内部没有保存任何内容,也没有给出原因的错误。

我确实尝试(在代码的早期版本中)在读取 MP3 文件的元数据后创建对象 - 但由于某种原因,它不会保存列表中的最后 2 个对象(共 12 个).. . 所以我重写了它,首先扫描所有项目,然后使用数组中的 mongoose 填充 mongoDB;只是为了把事情分开。但是没有运气找出为什么什么都没有发生以及为什么.save()没有错误

非常感谢任何帮助。

问候, 标记

【问题讨论】:

  • 好的,但是你是在别处调用你的 saveMP3s 函数,并传递一个回调函数吗?
  • 实际上该函数可以是 - 异步循环中的回调不会超出该函数。问题出在异步“循环”中,我认为如果我删除它,它将保存第一个对象。这回答了你的问题还是我完全不明白? :)
  • 我正在调用 saveMP3s 函数,使用"
  • 我调用函数使用:saveMP3s(json) - json 是多个我想保存为“newTrack”的项目
  • 我很确定@AlexFord 是对的。他看到了我们没有看到的。

标签: node.js asynchronous mongoose


【解决方案1】:
var saveMP3s = function(MP3Files, callback) {
  console.log('start loop -> saving MP3s');
  async.forEach( MP3Files, function(mp3file, callback) {
    var newTrack = new MP3Track(); // <--- USE VAR HERE
    newTrack.title = mp3file.title;
    newTrack.track = mp3file.track;
    newTrack.disk = mp3file.disk;
    newTrack.metadata = mp3file.metadata;
    newTrack.path = mp3file.path;
    console.log('....:> Song Start: ');
    console.log(newTrack.title);
    console.log(newTrack.track);
    console.log(newTrack.disk);
    console.log(newTrack.metadata);
    console.log(newTrack.path);
    console.log('....:> Song End: ');
    newTrack.save(function (err) {
      if (err) {
        console.log(err);
      } else {
        console.log('saving Track: '+ newTrack.title);
        callback();
      }
    });
  }, function(err) {
    if (err) { console.log(err); }
  });
  console.log('end loop -> finished saving MP3s');
};

我怀疑缺少的 var 关键字声明了一个全局变量,而您在循环的每次迭代中都覆盖了它。这意味着,在第一个 newTrack 可以完成它的异步保存操作之前,您已经在循环中继续前进并用下一个实例覆盖了该变量。

另外,在async.forEachMUST 在操作完成时调用回调。只有在记录成功保存时才调用它。如果发生错误,您也应该调用它并传递错误。

最后,saveMP3s 函数的 callback 参数根本不会被调用。 newTrack.save 函数内部对callback() 的调用仅指async.forEach 传递给匿名函数的回调参数。

【讨论】:

  • - 缺少的 Var(当你在写的时候)在循环方面并没有太大的区别——我尝试过使用和不使用局部变量定义。我也尝试在 .save() 函数之后使用 callbacks(),但不起作用。你有一个“理想的”异步循环吗?我已经尝试了这些示例-并且我的代码的其他区域使用了与我使用的相同样式的代码。所以有点卡住了-抱歉
【解决方案2】:

已解决

嗨,

我最终解决了这个问题,让异步循环在逻辑中更高,因此从异步循环本身中调用了 saveMP3s 函数。

感谢大家的意见和建议。

享受你的一天。

标记 (明天才可以接受我的答案,所以会更新问题状态)

【讨论】:

  • 您应该发布最终代码。我很想看看你的变化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-30
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多