So I usually deal with async functions by using the .then
chain. But this time it doesn't solve it. This is the situation.
return Promise.all([
Banner.findOne(),
event.findOne({
status: true
}),
Account.find({
accType: 'employer'
})
.then(([banner, event, account]) => {
res.render('index', {
title: 'Web Project Studio',
user: req.user,
banner: banner,
event: event,
employer: account
});
}).catch(e => {
console.error(e);
})
]);
So this worked, and all was great. But now I decided to change the way to select the active event
. I'm calling a collection called generalInfo
and grabbing the ID to the current event from there. Here's what I have so far:
return Promise.all([
Banner.findOne(),
GeneralInfo.findOne(),
Account.find({
accType: 'employer'
})
]).then(([banner, generalInfo, account]) => {
Event.findById(generalInfo.activeEventId).then(r => {
console.log('test');
var event = r;
res.render('index', {
title: 'Web Project Studio',
user: req.user,
banner: banner,
event: event,
employer: account
});
}).catch(e => console.log(e));
}
}).catch(e => {
console.error(e);
})
But this code starts to look like a callback hell.
I also tried something like this:
var banner = await Banner.findOne().catch(e => console.log(e));
var currentEvent = await GeneralInfo.findOne().catch(e => console.log(e));
currentEvent.then(async r => {
var event = await Event.findOneById(r.activeEventId).catch(e => console.log(e));
}).catch(e => console.log(e));
It's not completed but it kind of shows my way of thinking. But again, no luck.
So how can I get along with async without chaining .then
forever? I need to pass all the returned objects to the render
function.
You can just nest earlier, which has the advantage of overlapping more as well (see ***
comment(s)):
return Promise.all([
Banner.findOne(),
GeneralInfo.findOne()
.then(generalInfo => Event.findById(generalInfo.activeEventId)), // ***
Account.find({
accType: 'employer'
})
}).then(([banner, event, account]) => {
res.render('index', {
title: 'Web Project Studio',
user: req.user,
banner: banner,
event: event,
employer: account
});
}).catch(e => {
console.error(e);
});
If you do that generalInfo => event thing a lot, you might wrap it in a utility function.
Alternately, if they shouldn't overlap like that, you can minimize the nesting by adding another then
:
return Promise.all([
Banner.findOne(),
GeneralInfo.findOne(),
Account.find({
accType: 'employer'
})
]).then(([banner, generalInfo, account]) => {
return Event.findById(generalInfo.activeEventId).then(event => { // ***
return [banner, event, account]; // ***
}); // ***
}).then(([banner, event, account]) => {
res.render('index', {
title: 'Web Project Studio',
user: req.user,
banner: banner,
event: event,
employer: account
});
}).catch(e => {
console.error(e);
})
This should work.
return Promise.all([
Banner.findOne(),
GeneralInfo.findOne(),
Account.find({
accType: 'employer'
})
]).then(async ([banner, generalInfo, account]) => {
res.render('index', {
title: 'Web Project Studio',
user: req.user,
banner: banner,
event: await Event.findById(generalInfo.activeEventId),
employer: account
});
}).catch(e => {
console.error(e);
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.