2015-08-04 9 views
7

Ich bin leider neu zu Knoten und läuft in eine Verwirrung in Bezug auf die asynchrone/synchrone Ausführung des Knotens.Knoten + Sequelize: Wie kann man prüfen, ob Artikel vorhanden ist, bevor das Hinzufügen? (Asynchron-Verwirrung)

Ich bin mit Knoten, sequelize mit SQLite und async.js.

Ich habe eine Reihe von Articles, von denen jede eine Anzahl von Authors hat.

Für jede Authors in jedem Article, ich möchte überprüfen, ob die Author existiert. Wenn nicht, erstellen Sie es.

Das Problem ist, auf der ersten Ausführung, doppelte Autoren erstellt werden, nehme ich an durch die Existenz mit der Überprüfung ein Problem auf asynchrone Funktionalität verursacht.

Zum Beispiel mit dem Array: authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']

und dem Code:

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

Was mache ich falsch:

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() 
      }) 
     } 
     }) 
    }) 
    }) 

Auf dem ersten Durchlauf wird eine Tabelle erstellen? Mir scheint ein grundlegendes Konzept der asynchronen vs synchronen Ausführung in Node zu fehlen.

(Ich habe auch versucht async.eachSeries, die in Reihe ausgeführt werden soll, statt parallel?)

Edit: Etwas Refactoring, aber immer noch zu schaffen Duplikate

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() 
     }) 
     } 
    }) 
    }) 

Antwort

0

Ihre ändern jeder zu eachSeries und tatsächlich den Rückruf anrufen und Sie sollten golden sein.

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

Hm, dies nicht zu sein scheint funktioniert, ist es nur der erste Autor hinzufügen. – waffl

+0

Hat Ihr Author.create einen Rückruf unterstützen, wie ich in den Kommentaren erwähnt? – trex005

+0

Sorry, wie meinst du das? Die 'create' Methode ist [implementiert durch sequelize] (http://docs.sequelizejs.com/en/latest/api/model/#createvalues-options-promiseinstance) was zu einem Versprechen führt – waffl

6

Author.count nicht wirklich benötigt wird, es sei denn, Sie Notwendigkeit der Graf. Siehe findOrCreate().

Mit findOrCreate() Sie die folgenden haben könnten. (Herausgegeben trex005 des Snippet für diese)

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) { 
 
     console.log('Author already exists'); 
 
     } 
 

 
     console.log('Created author...'); 
 
     callback(); 
 
    }); 
 
    }) 
 
})

+0

Hallo Danke für die Antwort schafft, eigentlich habe ich versucht, 'findOrCreate' (und in etwas sauberen Schnipseln Refactoring hinzugefügt meine Antwort oben), aber 'findOrCreate' wurde alle möglichen Probleme mit sQLite-Absperr-/Datenbank Verriegelung verursacht -. anscheinend dies auch in postgres für einige Benutzer geschieht leider noch mein neues snippet tatsächlich nicht funktioniert, und nach wie vor ist die Schaffung Duplikate – waffl

+1

. btw @ joshua-f, können Sie statt dann Methode Spread-Methode für Versprechen Argumente seperating. Beispiel: '.spread (function (Autor, isCreated) {...});' –

+0

@AliBARIN Oh süß, wusste nicht, dass . –