Как раз этого делать не нужно. Вместо этого нужно понять идею асинхронного программирования. Все колбэки исполняются не по месту своего объявления, а тогда, когда к ним приходят данные, поэтому в Вашем примере кода сначала происходит
console.log(items_list);
а уже потом
items_list = data
И это хорошо, потому, что не происходит ожидания исполнения коллбеков, не происходит блокирования потока исполнения. Всю синхронную логику обработки полученных в коллбеке данных Вы можете написать прямо в коллбеке, а если нужно реализовать последовательный или параллельный вызов нескольких ассинхронных запросов (все, что связано с вводом/выводом, доступом к базе и файлам, например), то это можно сделать разными способами, самые популярные из них, это библиотека async и промисы. Я использую
https://github.com/caolan/async Например:
var async = require('async');
var items_list, users_list;
async.parallel([
function(callback) { // делаем первый запрос к базе
db.model('items').find({}, function (err, data) {
items_list = data;
callback(); // данные получены, возвращаемся
});
},
function(callback) { // параллельно делаем второй запрос к базе
db.model('users').find({}, function (err, data) {
users_list = data;
callback(); // данные получены, возвращаемся
});
}
],
function() {
// когда оба запроса уже завершены, то мы попадаем сюда
console.dir({ items: items_list, users: users_list });
});