Javascript 基于前一个调用的响应的异步调用,避免了回调地狱
因此,我通常使用Javascript 基于前一个调用的响应的异步调用,避免了回调地狱,javascript,node.js,mongodb,asynchronous,mongoose,Javascript,Node.js,Mongodb,Asynchronous,Mongoose,因此,我通常使用.then链来处理异步函数。但这一次并不能解决问题。情况就是这样 return Promise.all([ Banner.findOne(), event.findOne({ status: true }), Account.find({ accType: 'employer' }) .then(([banner, event, account]) => { re
.then
链来处理异步函数。但这一次并不能解决问题。情况就是这样
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);
})
]);
这一切都很成功,一切都很好。但是现在我决定改变选择活动事件的方式。我正在调用一个名为generalInfo
的集合,并从那里获取当前事件的ID。以下是我目前掌握的情况:
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);
})
但这段代码开始看起来像是一个地狱般的回调
我也试过这样的方法:
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));
它还没有完成,但它显示了我的思维方式。但同样,没有运气
那么,我如何才能在不链接的情况下与async相处呢?我需要将所有返回的对象传递给render
函数。您可以更早嵌套,这样做的优点是重叠更多(请参见***
注释):
如果您经常使用generalInfo=>事件,您可能会将其包装在一个实用函数中
或者,如果它们不应该像那样重叠,您可以通过添加另一个然后来最小化嵌套:
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);
})
您可以更早嵌套,这也有重叠更多的优点(请参见***
注释):
如果您经常使用generalInfo=>事件,您可能会将其包装在一个实用函数中
或者,如果它们不应该像那样重叠,您可以通过添加另一个然后来最小化嵌套:
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);
})
这应该行得通
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);
})
这应该行得通
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);
})
在我发布答案之前,我很好奇你是否愿意从你的承诺(或承诺)中创造一个可观察的结果。如果是这样的话,您可以将map、concat和所有这些伟大的可观察操作符合并在一起,它们可以让您以类似过程的方式(当然是异步的)完成这类工作。如果你对rxjs不感兴趣,尽管我不知道那是什么,但我完全支持任何答案。萨:你真的(真的!)需要查找“rxjs”并探索“可观察的”。基本上,它们允许您将数据表示为一个“流”,您可以将其与其他流合并,等待其他流准备就绪,等等。承诺对于它们所擅长的(几乎是即时一次执行)来说是好的,但是当您需要管理多个异步流时,特别是当它们需要按顺序管理、加入、重试等时,承诺在风格上开始崩溃。这需要一些努力,但是现在,如果你在做异步工作,你真的需要rxjs。无论如何,一个可观察的东西(代表异步数据流的东西)可以包装一个承诺,这样你就可以使用可观察的操作符等等。一定要查一下“rxjs中的多个流”,你会得到各种各样的教程和代码示例。谢谢在我发布答案之前,我很好奇你是否愿意从你的承诺(或承诺)中创造一个可观察的结果。如果是这样的话,您可以将map、concat和所有这些伟大的可观察操作符合并在一起,它们可以让您以类似过程的方式(当然是异步的)完成这类工作。如果你对rxjs不感兴趣,尽管我不知道那是什么,但我完全支持任何答案。萨:你真的(真的!)需要查找“rxjs”并探索“可观察的”。基本上,它们允许您将数据表示为一个“流”,您可以将其与其他流合并,等待其他流准备就绪,等等。承诺对于它们所擅长的(几乎是即时一次执行)来说是好的,但是当您需要管理多个异步流时,特别是当它们需要按顺序管理、加入、重试等时,承诺在风格上开始崩溃。这需要一些努力,但是现在,如果你在做异步工作,你真的需要rxjs。无论如何,一个可观察的东西(代表异步数据流的东西)可以包装一个承诺,这样你就可以使用可观察的操作符等等。一定要查一下“rxjs中的多个流”,你会得到各种各样的教程和代码示例。谢谢