Lige her:
Post.find({}, function(err, docs) {
if (docs.length == 0)
return res.send({ message: "No posts" });
Hvis du rammer den betingelse docs.length == 0
, så sender du et svar på anmodningen. Men din return
returnerer KUN fra Post.find()
ring tilbage. Det vender ikke tilbage fra dine trendingposts()
funktion.
Så i mellemtiden fortsætter den funktion med at udføre og kommer til sidst til denne kode:
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);
});
Hvor du så sender endnu et svar på samme anmodning. Det er det, der udløser fejlen Cannot set headers after they are sent to the client
som du ser.
Der er mange forskellige måder at forhindre dette på, men de er sandsynligvis alle relateret til, hvordan du generelt ville rydde op i denne funktion. Som det er skrevet nu, starter du i det væsentlige to fuldstændig adskilte asynkrone kodestier. Begge starter med Post.find({})
og gå derfra. De kører hver især parallelt og har ingen anelse om, hvad den anden kodesti gør. Som sådan har du ingen konkret måde at sende et svar fra den ene, men ikke begge.
Så måden at rydde op på er sandsynligvis ikke at have to fuldstændig adskilte asynkrone kodestier. Du skal koordinere dem på en eller anden måde. I stort set alle tilfælde her vil du gerne skifte over til løftegrænsefladen til din database, da det vil give dig mange flere muligheder for at styre dit kontrolflow. For eksempel, hvis du af præstationsmæssige årsager ønsker at have to parallelle asynkrone operationer i gang på én gang, med løfter, kan du bruge Promise.all()
eller Promise.allSettled()
at overvåge begge og vide, hvornår de er færdige og derefter, med begge resultater i hånden, beslutte, hvilket svar der skal sendes.
Eller, hvis du vil sekvensere dem, kan du bruge async/await
for ret nemt at rækkefølge de to operationer og derefter når du laver en return
, vil den faktisk vende tilbage fra funktionen på øverste niveau og stoppe yderligere kontrolflow.
Hvis du vil holde fast i callback-grænsefladen til din database, så bliver du sandsynligvis nødt til at indlejre den anden operation i den første mulighed, så du ikke starter den anden operation, hvis du skal udføre res.send({ message: "No posts" })
.