Chociaż twój kod nie obsługuje kilku przypadków błędów i używa niewłaściwego find
funkcji, ogólny przepływ jest typowy, dając pracę, którą chcesz wykonać.
- Jeśli występują błędy inne niż duplikat, wywołanie zwrotne nie jest wywoływane, co prawdopodobnie spowoduje problemy w aplikacji NodeJs
- użyj
findOne
zamiastfind
ponieważ będzie tylko jeden wynik, biorąc pod uwagę, że klucz jest unikalny. W przeciwnym razie zwróci tablicę. - Jeśli wywołanie zwrotne oczekiwało tradycyjnego
error
jako pierwszy argument możesz bezpośrednio przekazać wywołanie zwrotne dofindOne
funkcji zamiast wprowadzania funkcji anonimowej. - Możesz również spojrzeć na
findOneAndUpdate
ostatecznie, w zależności od ostatecznego schematu i logiki.
Jak wspomniano, możesz być w stanie użyć findOneAndUpdate
, ale za dodatkową opłatą.
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);
}
Oczywiście nadal istnieje wywołanie zwrotne, ale zapisze dane ponownie, jeśli zostanie znaleziony duplikat. To, czy jest to problem, zależy od przypadków użycia.
Zrobiłem trochę porządku w twoim kodzie... ale jest to naprawdę bardzo proste i wywołanie zwrotne powinno być jasne. callback
do funkcji zawsze otrzymuje albo nowo zapisany dokument, albo ten, który został dopasowany jako duplikat. Jest to odpowiedzialność funkcji wywołującej saveNewValue
aby sprawdzić błąd i prawidłowo go obsłużyć. Zobaczysz, jak upewniłem się, że wywołanie zwrotne jest wywoływane niezależnie od rodzaju błędu i zawsze jest wywoływane z wynikiem w spójny sposób.
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);
});
}
Alternatywnie możesz użyć obietnicy wzorzec. Ten przykład używa 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
});