简体   繁体   English

基于上一个调用的响应进行异步调用,避免了回调地狱

[英]Async call based on a response from a previous call, avoiding callback hell

So I usually deal with async functions by using the .then chain. 因此,我通常使用.then链处理异步函数。 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 . 但是现在我决定改变选择活动event I'm calling a collection called generalInfo and grabbing the ID to the current event from there. 我正在调用一个名为generalInfo的集合,并从那里获取当前事件的ID。 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? 所以,我怎么能相处异步无链接.then下去吗? I need to pass all the returned objects to the render function. 我需要将所有返回的对象传递给render函数。

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. 如果您经常执行generalInfo => event事情,则可以将其包装在实用程序函数中。

Alternately, if they shouldn't overlap like that, you can minimize the nesting by adding another then : 或者,如果它们不应该那样重叠,则可以通过添加另一个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);
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM