I když váš kód nezvládá několik případů chyb a používá nesprávné find
Obecný tok je typický pro práci, kterou chcete dělat.
- Pokud se vyskytnou jiné chyby než duplikát, zpětné volání se nevolá, což pravděpodobně způsobí následné problémy ve vaší aplikaci NodeJs
- použijte
findOne
spíše nežfind
protože bude pouze jeden výsledek, pokud je klíč jedinečný. V opačném případě vrátí pole. - Pokud vaše zpětné volání očekávalo tradiční
error
jako první argument můžete předat zpětné volání přímofindOne
funkci spíše než zavádění anonymní funkce. - Můžete se také podívat na
findOneAndUpdate
případně, v závislosti na tom, jaké bude vaše konečné schéma a logika.
Jak již bylo zmíněno, možná budete moci použít findOneAndUpdate
, ale s dodatečnými náklady.
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);
}
Samozřejmě stále existuje zpětné volání, ale pokud je duplikát nalezen, zapíše data znovu. Zda se jedná o problém, skutečně závisí na případech použití.
Udělal jsem malé vyčištění vašeho kódu... ale je to opravdu docela jednoduché a zpětné volání by mělo být jasné. callback
do funkce vždy obdrží buď nově uložený dokument, nebo ten, který byl spárován jako duplikát. Zodpovídá za to funkce volající saveNewValue
zkontrolovat chybu a správně ji ošetřit. Uvidíte, jak jsem se také ujistil, že zpětné volání je voláno bez ohledu na typ chyby a je vždy voláno s výsledkem konzistentním způsobem.
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);
});
}
Případně můžete použít slib vzor. Tento příklad používá 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
});