Hier:
Post.find({}, function(err, docs) {
if (docs.length == 0)
return res.send({ message: "No posts" });
Als u voldoet aan die voorwaarde van docs.length == 0
, dan stuurt u een reactie op het verzoek. Maar uw return
komt ALLEEN terug van de Post.find()
terugbellen. Het komt niet terug van je trendingposts()
functie.
Dus ondertussen blijft die functie uitvoeren en komt uiteindelijk bij deze code:
var mysort = { score: -1 };
Post.find({})
.populate("postedBy")
.populate("comments.postedBy")
.populate("comments.incomments.postedBy")
.populate("comments.likes")
.sort(mysort)
.limit(10)
.exec((er, result) => {
res.json(result);
});
Waar je vervolgens een ander antwoord op hetzelfde verzoek stuurt. Dat is wat de fout veroorzaakt Cannot set headers after they are sent to the client
die je ziet.
Er zijn veel verschillende manieren om dit te voorkomen, maar ze hebben waarschijnlijk allemaal te maken met hoe u deze functie over het algemeen zou opruimen. Zoals het nu is geschreven, begin je in wezen twee volledig afzonderlijke asynchrone codepaden. Beide beginnen met Post.find({})
en ga vanaf daar. Ze lopen elk parallel en geen van beiden heeft enig idee wat het andere codepad doet. Als zodanig heb je geen concrete manier om een antwoord te sturen van één, maar niet van beide.
Dus de manier om dit op te ruimen is waarschijnlijk om niet twee volledig gescheiden asynchrone codepaden te hebben. Je moet ze op de een of andere manier coördineren. In vrijwel alle gevallen hier, wil je overschakelen naar de belofte-interface naar je database, omdat dat je veel meer opties geeft voor het beheren van je controlestroom. Als u bijvoorbeeld om prestatieredenen twee parallelle asynchrone bewerkingen tegelijk wilt hebben, met beloften, kunt u Promise.all()
gebruiken of Promise.allSettled()
om beide te controleren en te weten wanneer ze klaar zijn en vervolgens, met beide resultaten in de hand, te beslissen welk antwoord te verzenden.
Of, als u ze in volgorde wilt zetten, kunt u async/await
. gebruiken om de twee bewerkingen vrij eenvoudig in volgorde te zetten en vervolgens wanneer u een return
. doet , het zal daadwerkelijk terugkeren van de functie op het hoogste niveau en zal de verdere controlestroom stoppen.
Als u de callback-interface naar uw database wilt behouden, moet u waarschijnlijk de tweede bewerking in de eerste optie nesten, zodat u de tweede bewerking niet start als u res.send({ message: "No posts" })
.