Nodejs异步数据重复

时间:2014-05-02 18:02:25

标签: arrays json node.js asynchronous

我对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);
    // }
  }
}

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

1 个答案:

答案 0 :(得分:2)

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

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

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

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

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

由于您在每个author电话中创建了新的process_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一样),但在执行回调后,您的程序会产生后果。

不确定这是否有效。

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