残念ながら、ノードは初めてであり、ノードの非同期/同期実行に関して混乱が生じています。
私はノードを使用しています。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()
})
}
})
})
_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();
});
})
})
_
それぞれを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();
})
}
})
})
})