Mens din kode ikke håndterer nogle få fejltilfælde og bruger den forkerte find
funktion, er det generelle flow typisk, hvilket giver det arbejde, du ønsker at udføre.
- Hvis der er andre fejl end duplikatet, kaldes tilbagekaldet ikke, hvilket sandsynligvis vil forårsage downstream-problemer i din NodeJs-applikation
- brug
findOne
i stedet forfind
da der kun vil være ét resultat, da nøglen er unik. Ellers returnerer den et array. - Hvis dit tilbagekald forventede den traditionelle
error
som det første argument kunne du sende tilbagekaldet direkte tilfindOne
funktion frem for at indføre en anonym funktion. - Du vil måske også kigge på
findOneAndUpdate
i sidste ende, afhængigt af hvad dit endelige skema og logik vil være.
Som nævnt kan du muligvis bruge findOneAndUpdate
, men med ekstra omkostninger.
function save(id, title, callback) {
Value.findOneAndUpdate(
{id: id, title: title}, /* query */
{id: id, title: title}, /* update */
{ upsert: true}, /* create if it doesn't exist */
callback);
}
Der er selvfølgelig stadig et tilbagekald, men det vil skrive dataene igen, hvis duplikatet er fundet. Hvorvidt det er et problem, afhænger virkelig af use cases.
Jeg har ryddet lidt op i din kode... men det er egentlig ret simpelt, og tilbagekaldet burde være klart. callback
til funktionen modtager altid enten det nyligt gemte dokument eller det, der blev matchet som et dublet. Det er ansvaret for den funktion, der kalder saveNewValue
at kontrollere for en fejl og håndtere den korrekt. Du vil se, hvordan jeg også har sikret mig, at tilbagekaldet kaldes uanset type fejl og altid kaldes med resultatet på en ensartet måde.
function saveNewValue(id, title, callback) {
if (!callback) { throw new Error("callback required"); }
var thisValue = new models.Value({
id:id,
title:title //this is a unique value
});
thisValue.save(function(err, product) {
if (err) {
if (err.code === 11000) { //error for dupes
return models.Value.findOne({title:title}, callback);
}
}
callback(err, product);
});
}
Alternativt kan du bruge løftet mønster. Dette eksempel bruger when.js .
var when = require('when');
function saveNewValue(id, title) {
var deferred = when.defer();
var thisValue = new models.Value({
id:id,
title:title //this is a unique value
});
thisValue.save(function(err, product) {
if (err) {
if (err.code === 11000) { //error for dupes
return models.Value.findOne({title:title}, function(err, val) {
if (err) {
return deferred.reject(err);
}
return deferred.resolve(val);
});
}
return deferred.reject(err);
}
return deferred.resolve(product);
});
return deferred.promise;
}
saveNewValue('123', 'my title').then(function(doc) {
// success
}, function(err) {
// failure
});