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
findOnespíše nežfindprotož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í
errorjako první argument můžete předat zpětné volání přímofindOnefunkci spíše než zavádění anonymní funkce. - Můžete se také podívat na
findOneAndUpdatepří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
});