Для начала разбор Вашего варианта:
var all_mail;
mailModel.find().exec((err, docs) =>{
// данный код не будет выполнен сразу, он будет выполнен только через какоето время.
// дело в том, что пока бд сделает выборку и отдаст результат
// может пройти определенное время. Чтобы избежать простоев,
// в данном случае метод exec выполняется асинхронно
// то есть тело данной функции будет вызвано не ранее чем от БД будут получены данные
// а js тем временем продолжит выполнение кода дальше
all_mail = docs;
});
// и придет сюда. но так как docs от БД еще не получен, all_mail все еще равен undefined.
console.log(all_mail); // Ошибка
Теперь посмотрим как же нам добиться своевременной обработки результата:
// добро пожаловать в асинхронность
var all_mail;
mailModel.find().exec((err, docs) =>{
// в all_mail засовываем промис(обещание) того, что в скором времени будет результат
all_mail = new Promise((resolve, reject)=>{
resolve(docs);
});
});
all_mail.then((data)=>{
// когда же результат будет получен, обрабатываем его
console.log(data); // все ок)
});