Niestety, nie jestem nowy w węźle i mam pewne zamieszanie dotyczące asynchronicznego/synchronicznego wykonywania węzła.Węzeł + Sequelize: Jak sprawdzić, czy element istnieje przed dodaniem? (asynchroniczne zamieszanie)
Używam węzła, kontynuuj pracę z sqlite i async.js.
Mam serię Articles
, z których każda ma numer Authors
.
Dla każdego Authors
w każdym Article
, chciałbym sprawdzić, czy istnieje Author
. Jeśli nie, utwórz go.
Problem polega na tym, że przy pierwszym uruchomieniu tworzony jest zduplikowany autor, zakładam ze względu na asynchroniczną funkcjonalność powodującą problem z sprawdzaniem istnienia.
Na przykład, przy tablicy: authors = ['A. Test', 'B. Test', 'C. Test', 'A. Test']
i kod:
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()
})
}
})
})
})
Na pierwszym biegu, stworzy tabelę:
ID | name
------------
0 | A. Test
1 | B. Test
2 | C. Test
3 | A. Test
Co robię źle? Wygląda na to, że brakuje mi podstawowej koncepcji wykonania asynchronicznego vs synchronicznego w węźle.
(Próbowałem też async.eachSeries która ma wykonać szeregowo zamiast równolegle?)
EDIT: Lekko refactored, ale nadal tworzenie duplikatów
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()
})
}
})
})
Hm, to nie wydaje się działać, to dodanie tylko pierwszego autora. – waffl
Czy Twój Author.create obsługuje wywołanie zwrotne, o którym wspomniałem w komentarzach? – trex005
Przepraszam, jak masz na myśli? Metoda 'create' jest [implementowana przez sequelize] (http://docs.sequelizejs.com/en/latest/api/model/#createvalues-options-promiseinstance), co skutkuje obietnicą. – waffl