Reputation: 25
This function triggers on getinitialprops which waits for it to finish before render. Is there any way to gain speed versus waiting for this long query to finish?
exports.getAppStats = (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
const stats = {}
Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } })
.then((result) => {
stats.today = result
Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } })
.then((result) => {
stats.sevenDays = result
Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } })
.then((result) => {
stats.thirtyDays = result
Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } })
.then((result) => {
stats.year = result
return res.json(stats);
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}).catch(err => console.log(err))
}
Upvotes: 2
Views: 57
Reputation: 11116
This is where you can leverage the Promise.all()
function to run all of your queries in parallel and then wait until all of them are finished, like so:
exports.getAppStats = (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
const stats = {}
// get promises for each query
let today = Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } });
let sevenDays = Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } });
let thirtyDays = Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } });
let year = Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } });
// wait until all promises have been resolved, then set stats & send response
Promise.all([today, sevenDays, thirtyDays, year]).then(([todayData, sevenDaysData, thirtyDaysData, yearData]) => {
stats = {
today: todayData,
sevenDays: sevenDaysData,
thirtyDays: thirtyDaysData,
year: yearData
}
res.status(200).json({data: stats});
}, (err) => {
console.log(err);
// next(err);
// res.status(500).json({ message: "Something went wrong..." });
});
}
Alternatively, you can use the async/await
keywords to avoid callbacks, altogether. Although it will require a try/catch
to handle errors. Honestly it makes no difference, it's purely preference.
// note this is now an async function
exports.getAppStats = async (req, res, next) => {
const startToday = moment(req.query.today).startOf('day');
const endToday = moment(req.query.today).endOf('day');
const startsevenDays = moment(req.query.today).subtract(7, 'd').startOf('day');
const startThirtyDays = moment(req.query.today).subtract(30, 'd').startOf('day');
const startYear = moment(req.query.today).subtract(365, 'd').startOf('day');
// get promises for each query
let today = Application.countDocuments({ dateTime: { $gte: startToday, $lte: endToday } });
let sevenDays = Application.countDocuments({ dateTime: { $gte: startsevenDays, $lte: endToday } });
let thirtyDays = Application.countDocuments({ dateTime: { $gte: startThirtyDays, $lte: endToday } });
let year = Application.countDocuments({ dateTime: { $gte: startYear, $lte: endToday } });
try {
// wait until all promises have been resolved, then set stats & send response
// await Promise.all instead of using callbacks
let [todayData, sevenDaysData, thirtyDaysData, yearData] = await Promise.all(
[today, sevenDays, thirtyDays, year]
);
let stats = {
today: todayData,
sevenDays: sevenDaysData,
thirtyDays: thirtyDaysData,
year: yearData
}
res.status(200).json({data: stats});
} catch(err) {
console.log(err);
// next(err);
// res.status(500).json({ message: "Something went wrong..." });
}
}
Upvotes: 4