I recommend reading about Promise and using Promise.all .
In short: this method accepts an array of promises and will be fulfilled when all promises are fulfilled (promises)
const p1 = Promise.resolve(3); const p2 = new Promise((resolve, reject) => { setTimeout(resolve, 100, "foo"); }); Promise.all([p1, p3]).then(values => { console.log(values); // [3, "foo"] через 0.1сек });
For your case, p1 and p2 should return promises that the data will load (just wrap your methods in promises, and resolve() in callbacks).
Alternative option:
const users = null; const categories = null const sendData = () => { if (users && categories) { res.json({ users, categories }); // next(); } }; User.find({}, (err, u) => { users = u; sendData(); }); Category.find({}, (err, c) => { categories = c; sendData(); });
Another option is to use a chain of callbacks, but then performance is lost, although this is the simplest option that was almost always used before the appearance of ES6.