U zou uw oproepen moeten nesten om de product-ID van het andere model te verwijderen. Bijvoorbeeld in uw oproep om het product te verwijderen uit het Product
collectie, kunt u ook nog een oproep doen om de ref te verwijderen van de Partner
model binnen de resultaten callback. Als u het product standaard verwijdert, worden de verwijzingen naar de Campaign
verwijderd Model.
De volgende code toont de intuïtie hierboven:
var campSchema = require('../model/camp-schema');
router.post('/removeProduct', function (req, res) {
campSchema.Product.findOneAndRemove({ _id: req.body.productId }, function (err, response) {
if (err) throw err;
campSchema.Partner.update(
{ "products": req.body.productId },
{ "$pull": { "products": req.body.productId } },
function (err, res){
if (err) throw err;
res.json(res);
}
);
});
});
Om de bijbehorende campagnes te verwijderen, heeft u mogelijk een extra verwijderingsbewerking nodig waarbij de bijbehorende campagne-ID van een bepaalde product-ID wordt overgenomen. Overweeg de volgende vuile hack die u mogelijk een enkeltje kan opleveren voor callback hell indien niet voorzichtig met het terugbellen nesten:
router.post('/removeProduct', function (req, res) {
campSchema.Product.findOneAndRemove(
{ _id: req.body.productId },
{ new: true },
function (err, product) {
if (err) throw err;
campSchema.Partner.update(
{ "products": req.body.productId },
{ "$pull": { "products": req.body.productId } },
function (err, res){
if (err) throw err;
var campaignList = product.campaign
campSchema.Campaign.remove({ "_id": { "$in": campaignList } })
.exec(function (err, res){
if (err) throw err;
res.json(product);
})
}
);
}
);
});
Hoewel het werkt, kan de bovenstaande potentiële valkuil worden vermeden door async/wait of de async
bibliotheek. Maar eerst, om u een beter begrip te geven van het gebruik van meerdere callbacks met de async
module, laten we dit illustreren met een voorbeeld uit Seven Dingen die u niet meer moet doen met Node.js
van meerdere bewerkingen met callbacks om een bovenliggende entiteit te vinden en vervolgens onderliggende entiteiten te vinden die bij de bovenliggende entiteit horen:
methodA(function(a){
methodB(function(b){
methodC(function(c){
methodD(function(d){
// Final callback code
})
})
})
})
Met async/wait worden uw gesprekken geherstructureerd als
router.post('/removeProduct', async (req, res) => {
try {
const product = await campSchema.Product.findOneAndRemove(
{ _id: req.body.productId },
{ new: true }
)
await campSchema.Partner.update(
{ "products": req.body.productId },
{ "$pull": { "products": req.body.productId } }
)
await campSchema.Campaign.remove({ "_id": { "$in": product.campaign } })
res.json(product)
} catch(err) {
throw err
}
})
Met de async-module kunt u ofwel de seriemethode gebruiken om het gebruik van callbacks voor het nesten van code van meerdere methoden aan te pakken, wat kan resulteren in Hel terugbellen :
Serie :
async.series([
function(callback){
// code a
callback(null, 'a')
},
function(callback){
// code b
callback(null, 'b')
},
function(callback){
// code c
callback(null, 'c')
},
function(callback){
// code d
callback(null, 'd')
}],
// optional callback
function(err, results){
// results is ['a', 'b', 'c', 'd']
// final callback code
}
)
Of de waterval :
async.waterfall([
function(callback){
// code a
callback(null, 'a', 'b')
},
function(arg1, arg2, callback){
// arg1 is equals 'a' and arg2 is 'b'
// Code c
callback(null, 'c')
},
function(arg1, callback){
// arg1 is 'c'
// code d
callback(null, 'd');
}], function (err, result) {
// result is 'd'
}
)
Ga nu terug naar uw code, met behulp van de asynchrone watervalmethode zou u uw code vervolgens kunnen herstructureren naar
router.post('/removeProduct', function (req, res) {
async.waterfall([
function (callback) {
// code a: Remove Product
campSchema.Product.findOneAndRemove(
{ _id: req.body.productId },
function (err, product) {
if (err) callback(err);
callback(null, product);
}
);
},
function (doc, callback) {
// code b: Remove associated campaigns
var campaignList = doc.campaign;
campSchema.Campaign
.remove({ "_id": { "$in": campaignList } })
.exec(function (err, res) {
if (err) callback(err);
callback(null, doc);
}
);
},
function (doc, callback) {
// code c: Remove related partner
campSchema.Partner.update(
{ "products": doc._id },
{ "$pull": { "products": doc._id } },
function (err, res) {
if (err) callback(err);
callback(null, doc);
}
);
}
], function (err, result) {
if (err) throw err;
res.json(result); // OUTPUT OK
});
});