web-dev-qa-db-ja.com

Node + Sequelize:追加する前にアイテムが存在するかどうかを確認する方法は?(非同期の混乱)

残念ながら、ノードは初めてであり、ノードの非同期/同期実行に関して混乱が生じています。

私はノードを使用しています。sqliteとasync.jsで続編します。

一連のArticlesがあり、それぞれにAuthorsがいくつかあります。

Authorsの各Articleについて、Authorが存在するかどうかを確認したいと思います。そうでない場合は、作成します。

問題は、最初の実行時に重複する作成者が作成されていることです。非同期機能が存在の確認に問題を引き起こしているためだと思います。

たとえば、配列:authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']

そしてコード:

async.each(authors, function(item, callback){
    Author.sync().then(function(){
      Author.count({ where: {name: item.trim()} }).then(function(count){
        if (count != 0) {
          console.log('Author already exists')
        } else {
          console.log('Creating author...')
          Author.create({
            name: item.trim()
          })
        }
      })
    })
  })

最初の実行時に、テーブルを作成します:

ID | name
------------
0  | A. Test
1  | B. Test
2  | C. Test
3  | A. Test

私は何を間違えていますか? Nodeでの非同期実行と同期実行の基本概念が欠けているようです。

(並列ではなく直列で実行することになっているasync.eachSeriesも試しましたか?)

編集:わずかにリファクタリングされましたが、重複を作成しています

async.eachSeries(authors, function(authorName, callback){
    Author.findOne({ where: {name: authorName.trim()} }).
    then(function(author){
      if (author) {
        // Author exists...
        callback()
      } else {
        // Author does not exist...
        Author.create({
          name: authorName.trim()
        }).then(function(author){
          callback()
        })
      }
    })
  })
15
waffl

_Author.count_は、カウントが必要なneedでない限り、本当に必要ありません。 findOrCreate() を参照してください。

findOrCreate()を使用すると、次のことができます。 (このためにtrex005のスニペットを編集しました)

_async.eachSeries(authors, function(item, callback) {
  Author.sync().then(function() {
    Author.findOrCreate({
      where: {
        name: item.trim()
      },
      defaults: { // set the default properties if it doesn't exist
        name: item.trim()
      }
    }).then(function(result) {
      var author = result[0], // the instance of the author
        created = result[1]; // boolean stating if it was created or not

      if (!created) { // false if author already exists and was not created.
        console.log('Author already exists');
      }

      console.log('Created author...');
      callback();
    });
  })
})_
14
Joshua F

それぞれをeachSeriesに変更し、実際にコールバックを呼び出してください。

async.eachSeries(authors, function(item, callback){
    Author.sync().then(function(){
      Author.count({ where: {name: item.trim()} }).then(function(count){
        if (count != 0) {
          console.log('Author already exists')
          callback(); //assuming you want it to keep looping, if not use callback(new Error("Author already exists"))
        } else {
          console.log('Creating author...')
          Author.create({
            name: item.trim()
          }).then(function(author){
            callback();
          })
        }
      })
    })
  })
0
trex005