Di sini:
Post.find({}, function(err, docs) {
if (docs.length == 0)
return res.send({ message: "No posts" });
Jika Anda mencapai kondisi docs.length == 0
, maka Anda akan mengirimkan tanggapan atas permintaan tersebut. Tapi, return
. Anda HANYA kembali dari Post.find()
panggilan balik Itu tidak kembali dari trendingposts()
your Anda fungsi.
Jadi, sementara itu, fungsi itu terus dijalankan dan akhirnya mendapatkan kode ini:
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);
});
Di mana Anda kemudian mengirim tanggapan lain untuk permintaan yang sama. Itulah yang memicu kesalahan Cannot set headers after they are sent to the client
yang Anda lihat.
Ada banyak cara berbeda untuk mencegahnya, tetapi semuanya mungkin terkait dengan cara Anda membersihkan fungsi ini secara umum. Cara penulisannya sekarang, pada dasarnya Anda memulai dua jalur kode asinkron yang sepenuhnya terpisah. Keduanya dimulai dengan Post.find({})
dan pergi dari sana. Mereka masing-masing berjalan secara paralel dan tidak ada yang tahu apa yang dilakukan jalur kode lainnya. Dengan demikian, Anda tidak memiliki cara konkret untuk mengirim tanggapan dari satu, tetapi tidak keduanya.
Jadi, cara untuk membersihkannya mungkin adalah dengan tidak memiliki dua jalur kode asinkron yang sepenuhnya terpisah. Anda perlu mengoordinasikan mereka dalam beberapa cara. Dalam hampir semua kasus di sini, Anda akan ingin beralih ke antarmuka janji ke database Anda karena itu akan memberi Anda lebih banyak opsi untuk mengelola aliran kontrol Anda. Misalnya, jika karena alasan kinerja, Anda ingin menjalankan dua operasi asinkron paralel sekaligus, dengan janji, Anda dapat menggunakan Promise.all()
atau Promise.allSettled()
untuk memantau keduanya dan mengetahui kapan mereka selesai dan kemudian, dengan kedua hasil di tangan, memutuskan tanggapan mana yang akan dikirim.
Atau, jika Anda ingin mengurutkannya, Anda dapat menggunakan async/await
untuk mengurutkan dua operasi dengan cukup mudah dan kemudian ketika Anda melakukan return
, itu akan benar-benar kembali dari fungsi tingkat atas dan akan menghentikan aliran kontrol lebih lanjut.
Jika Anda ingin tetap menggunakan antarmuka panggilan balik ke database Anda, maka Anda mungkin harus menyarangkan operasi kedua ke opsi pertama sehingga Anda tidak memulai operasi kedua jika Anda akan melakukan res.send({ message: "No posts" })
.