You're missing a callback function to your iterator. If you check the documentation (link here), under the arguments list the second argument (the iterator) to each
takes both message and a callback. Here's the excerpt:
iterator(item, callback) - A function to apply to each item in the array. The iterator is passed a callback(err) which must be called once it has completed. If no error has occured, the callback should be run without arguments or with an explicit null argument.
async will only run your final callback once all your iterator functions are finished - and invoking the callback to the iterator is how async keeps track of how many are complete.
Try the following:
app.get("/getMessages", function (req, res) {
var JSONtoSend = [];
getAllMessages(req.session.cur_user, function ( messages ) {
console.log("10");
async.each(messages, function (message, callback) {
console.log("12");
User.findById(message.senderId, function (sender) {
console.log("20");
User.findById(message.recieverId, function (reciever) {
console.log("26");
JSONtoSend.push({ content:message.content, reciever: reciever, sender: sender });
callback();
});
});
}, function (err) { // this is the callback
if (err) {
console.log(err);
} else {
console.log("30");
res.json(JSONtoSend);
}
});
});
});
Ideally you would also pass any possible errors to callback()