sql >> Databáze >  >> NoSQL >> MongoDB

Proč se mi zobrazují hlavičky Nelze nastavit poté, co jsou odeslány chybě klienta v Nodejs?

Přímo zde:

Post.find({}, function(err, docs) {
    if (docs.length == 0)
        return res.send({ message: "No posts" });

Pokud splníte podmínku docs.length == 0 , poté zašlete odpověď na požadavek. Ale return se vrací POUZE z Post.find() zpětné volání. Nevrací se z vašich trendingposts() funkce.

Takže mezitím tato funkce pokračuje v provádění a nakonec se dostane k tomuto kódu:

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);
    });

Kde pak pošlete další odpověď na stejnou žádost. To je to, co spouští chybu Cannot set headers after they are sent to the client které vidíte.

Existuje mnoho různých způsobů, jak tomu zabránit, ale pravděpodobně všechny souvisí s tím, jak byste tuto funkci obecně vyčistili. Jak je nyní napsáno, v podstatě spustíte dvě zcela samostatné asynchronní kódové cesty. Oba začínají Post.find({}) a jít odtud. Každý běží paralelně a ani jeden nemá ponětí, co dělá druhá cesta kódu. Jako takový nemáte žádný konkrétní způsob, jak odeslat odpověď od jednoho, ale ne od obou.

Takže způsob, jak to vyčistit, je pravděpodobně nemít dvě zcela oddělené asynchronní kódové cesty. Musíte je nějakým způsobem koordinovat. V podstatě ve všech případech zde budete chtít přepnout na příslibové rozhraní vaší databáze, protože to vám poskytne mnohem více možností pro správu toku kontroly. Pokud například z důvodů výkonu chcete mít dvě paralelní asynchronní operace najednou, s přísliby, můžete použít Promise.all() nebo Promise.allSettled() sledovat obojí a vědět, kdy jsou hotové, a pak se s oběma výsledky rozhodnout, kterou odpověď odeslat.

Nebo, pokud je chcete sekvenovat, můžete použít async/await poměrně snadno seřadit obě operace a poté, když provedete return , skutečně se vrátí z funkce nejvyšší úrovně a zastaví další tok ovládání.

Pokud chcete zůstat u rozhraní zpětného volání do vaší databáze, pak budete pravděpodobně muset druhou operaci vnořit do první možnosti, abyste nespustili druhou operaci, pokud budete provádět res.send({ message: "No posts" }) .




  1. MongoDB $in Query Operator

  2. MongoDB $atanh

  3. Stránkování na poli uloženém v poli dokumentu

  4. MongoDB nezpracovává agregaci pomocí allowDiskUsage:True