MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Dlaczego otrzymuję błąd Nie można ustawić nagłówków po ich wysłaniu do klienta w Nodejs?

Właśnie tutaj:

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

Jeśli trafisz na ten warunek docs.length == 0 , wtedy wyślesz odpowiedź na żądanie. Ale Twój return zwraca TYLKO z Post.find() oddzwonić. Nie wraca z twoich trendingposts() funkcja.

W międzyczasie ta funkcja kontynuuje wykonywanie i ostatecznie dociera do tego kodu:

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

Następnie wysyłasz kolejną odpowiedź na to samo żądanie. To właśnie powoduje błąd Cannot set headers after they are sent to the client które widzisz.

Istnieje wiele różnych sposobów, aby temu zapobiec, ale prawdopodobnie wszystkie są związane z tym, w jaki sposób generalnie czyścisz tę funkcję. Sposób, w jaki jest teraz napisany, zasadniczo zaczyna się od dwóch całkowicie oddzielnych asynchronicznych ścieżek kodu. Oba zaczynają się od Post.find({}) i idź stamtąd. Każdy z nich działa równolegle i żaden nie ma pojęcia, co robi druga ścieżka kodu. W związku z tym nie masz konkretnego sposobu na wysłanie odpowiedzi od jednego, ale nie od obu.

Tak więc sposobem na uporządkowanie tego jest prawdopodobnie nie posiadanie dwóch całkowicie oddzielnych asynchronicznych ścieżek kodu. Musisz je w jakiś sposób skoordynować. W prawie wszystkich przypadkach będziesz chciał przełączyć się na interfejs obietnicy do swojej bazy danych, ponieważ zapewni to znacznie więcej opcji zarządzania przepływem kontroli. Na przykład, jeśli ze względu na wydajność chcesz mieć jednocześnie dwie równoległe operacje asynchroniczne, z obietnicami, możesz użyć Promise.all() lub Promise.allSettled() monitorować oba i wiedzieć, kiedy są skończone, a następnie, mając oba wyniki w ręku, zdecydować, którą odpowiedź wysłać.

Lub, jeśli chcesz je sekwencjonować, możesz użyć async/await dość łatwo sekwencjonować dwie operacje, a następnie, gdy wykonasz return , faktycznie powróci z funkcji najwyższego poziomu i zatrzyma dalszy przepływ sterowania.

Jeśli chcesz pozostać przy interfejsie wywołań zwrotnych do swojej bazy danych, prawdopodobnie będziesz musiał zagnieździć drugą operację w pierwszej opcji, aby nie uruchamiać drugiej operacji, jeśli zamierzasz wykonać res.send({ message: "No posts" }) .




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Jak pobrać wartość z mongoDB według nazwy klucza?

  2. MongoDB:Mapuj zagnieżdżoną tablicę w funkcji agregującej

  3. Najpopularniejsze bazy danych NoSQL obsługiwane przez ClusterControl

  4. Wstaw wiele plików JSON do MongoDB za pomocą Pythona

  5. Grupuj według sumy mongodb