Während Ihr Code einige Fehlerfälle nicht behandelt und den falschen find
verwendet Funktion, der allgemeine Ablauf ist typisch für die Arbeit, die Sie erledigen möchten.
- Wenn andere Fehler als das Duplikat vorhanden sind, wird der Rückruf nicht aufgerufen, was wahrscheinlich nachgelagerte Probleme in Ihrer NodeJs-Anwendung verursachen wird
- verwenden Sie
findOne
stattfind
da es nur ein Ergebnis geben wird, wenn der Schlüssel eindeutig ist. Andernfalls wird ein Array zurückgegeben. - Wenn Ihr Rückruf den traditionellen
error
erwartet hat Als erstes Argument könnten Sie den Rückruf direkt anfindOne
übergeben Funktion, anstatt eine anonyme Funktion einzuführen. - Sie können sich auch
findOneAndUpdate
ansehen schließlich, je nachdem, wie Ihr endgültiges Schema und Ihre Logik aussehen werden.
Wie bereits erwähnt, können Sie möglicherweise findOneAndUpdate
verwenden , aber mit zusätzlichen Kosten.
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);
}
Es gibt natürlich immer noch einen Rückruf, aber er schreibt die Daten erneut, wenn das Duplikat gefunden wird. Ob das ein Problem ist, hängt wirklich von den Anwendungsfällen ab.
Ich habe Ihren Code ein wenig aufgeräumt ... aber es ist wirklich ganz einfach und der Rückruf sollte klar sein. Der callback
erhält die Funktion immer entweder das neu gespeicherte Dokument oder dasjenige, das als Duplikat gematcht wurde. Es liegt in der Verantwortung der Funktion, die saveNewValue
aufruft um nach einem Fehler zu suchen und ihn richtig zu behandeln. Sie werden sehen, wie ich auch dafür gesorgt habe, dass der Callback unabhängig von der Art des Fehlers aufgerufen wird und immer konsistent mit dem Ergebnis aufgerufen wird.
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);
});
}
Alternativ können Sie das Versprechen verwenden Muster. Dieses Beispiel verwendet 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
});