【问题标题】:Nodejs async data duplicationNodejs异步数据复制
【发布时间】:2014-06-19 11:59:35
【问题描述】:

我在 nodejs 上的一个异步进程遇到了一些问题。

我从远程 JSON 获取一些数据并将其添加到我的数组中,这个 JSON 有一些重复的值,我需要在添加之前检查它是否已经存在于我的数组中以避免数据重复。

我的问题是,当我开始 JSON 值之间的循环时,循环调用下一个值之前的最新处理完成,因此,我的数组填充了重复的数据,而不是每个类型只维护一个项目。

看看我当前的代码:

BookRegistration.prototype.process_new_books_list = function(data, callback) {
    var i    = 0,
        self = this;
    _.each(data, function(book) {
      i++;
      console.log('\n\n ------------------------------------------------------------ \n\n');
      console.log('BOOK: ' + book.volumeInfo.title);
      self.process_author(book, function() { console.log('in author'); });
      console.log('\n\n ------------------------------------------------------------');
      if(i == data.length) callback();
    })
  }

BookRegistration.prototype.process_author = function(book, callback) {
  if(book.volumeInfo.authors) {
    var author = { name: book.volumeInfo.authors[0].toLowerCase() };
    if(!this.in_array(this.authors, author)) {
      this.authors.push(author);
      callback();
    }
  }
}

BookRegistration.prototype.in_array = function(list, obj) {
  for(i in list) { if(list[i] === obj) return true; }
  return false;
} 

结果是:

[{name: author1 }, {name: author2}, {name: author1}]

我需要:

[{name: author1 }, {name: author2}]

更新:

@Zub 建议的解决方案适用于数组,但不适用于 sequelize 和 mysql 数据库。

当我尝试将作者列表保存到数据库时,数据重复,因为系统在完成保存最后一个之前开始保存另一个数组元素。

这个案例的正确模式是什么?

我使用数据库的代码是:

BookRegistration.prototype.process_author = function(book, callback) {
  if(book.volumeInfo.authors) {
    var author = { name: book.volumeInfo.authors[0].toLowerCase() };
    var self   = this;
    models.Author.count({ where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(count) {
      if(count < 1) { 
        models.Author.create(author).success(function(author) {
          console.log('SALVANDO AUTHOR');
          self.process_publisher({ book:book, author:author }, callback);
        });
      } else {
        models.Author.find({where: { name: book.volumeInfo.authors[0].toLowerCase() }}).success(function(author) {
          console.log('FIND AUTHOR');
          self.process_publisher({ book:book, author:author }, callback);
        });        
      }
    });
    // if(!this.in_array(this.authors, 'name', author)) {
    //   this.authors.push(author);
    //   console.log('AQUI NO AUTHOR');
    //   this.process_publisher(book, callback);
    // }
  }
}

如何避免异步进程中的数据重复?

【问题讨论】:

    标签: arrays json node.js asynchronous


    【解决方案1】:

    这是因为你在比较不同的对象,结果总是false

    仅用于控制台中的实验类型:

    var obj1 = {a:1};
    var obj2 = {a:1};
    obj1 == obj2;    //false
    

    当比较对象(以及数组)时,只有当obj1 链接到obj2 时才会产生true

    var obj1 = {a:1};
    var obj2 = obj1;
    obj1 == obj2;    //true
    

    由于您在每个 process_author 调用中创建了新的 author 对象,因此在比较时您总是会得到 false

    在您的情况下,解决方案是比较每本书的 name 属性:

    BookRegistration.prototype.in_array = function(list, obj) {
      for(i in list) { if(list[i].name === obj.name) return true; }
      return false;
    }
    


    编辑(与您的评论问题相关):

    我会重写process_new_books_list方法如下:

    BookRegistration.prototype.process_new_books_list = function(data, callback) {
        var i = 0,
            self = this;
        (function nextBook() {
            var book = data[i];
            if (!book) {
                callback();
                return;
            }
            self.process_author(book, function() {
                i++;
                nextBook();
            });
        })();
    }
    

    在这种情况下,下一个process_author 不会立即被调用(就像_.each),而是在执行回调之后,所以你的程序有后果。

    但不确定这是否有效。

    对不起我的英语,我不是以英语为母语的人

    【讨论】:

    • 嗨,它工作正常,但现在,我有另一个相关的问题,当我执行相同的过程但使用数据库时,数据是重复的。我认为这是因为数据库进程的延迟更大,并且循环在完成处理最后一个之前开始处理新作者。我使用数据库用代码更新我的问题。你能看看吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 2015-04-21
    • 2018-06-08
    • 2014-08-05
    • 1970-01-01
    相关资源
    最近更新 更多