避免节点中发生回调地狱 [英] Avoiding callback hell in node

查看:53
本文介绍了避免节点中发生回调地狱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个功能

/* GET main page */
router.get('/', (req, res, next) => {
    Account.find({accType: 'Employer'}, (err, col) => {
        if (err) {
            console.log(err);
        } else {
            Banner.findOne((err, banner) => {
                if (err) {
                    console.log(err);
                } else {
                    // Determine whether there is at least one awaiting account.
                    Account.findOne({accType: 'Awaiting'}, (err, doc) => {
                            if (err) {
                                console.log(err);
                            } else {
                                if (doc != null) {
                                    var awaiting = true;
                                }
                                console.log(doc);
                                res.render('admin/', {
                                    title: 'Admin pannel',
                                    user: req.user,
                                    employers: col,
                                    areAwaiting: awaiting,
                                    banner: banner,
                                )
                            }
                        }
                    );
                }
            });
        }
    });
});

我尝试使用异步模块,如下所示:

I tried using the async module like this:

async.parallel(calls, (err, col) => {
    if (err)
        console.log(err);
    else {
        console.log(col);
        res.render('admin/', {
            title: 'Admin pannel',
            user: req.user,
            employers: col[0],
            banner: col[1],
            areAwaiting: col[2],
        })
    }
});

现在.我收到的错误是 wrapAsync(...)不是函数.我试图将我的函数放在这样的匿名函数中:

Now. The error I'm getting is wrapAsync(...) is not a function. I tried putting my functions in anonymous functions like this:

() => {
    Account.find({accType: 'Employer'}, (err, col) => {
        if (err)
            console.log(err);
        else return col;
    })
}

,但是代码只是冻结了.我也尝试过这个:

but then the code just freezes. I also tried this:

(col) => {
    Banner.findOne((err, doc) => {
        if (err)
            console.log(err);
        else return doc;
    });
    return col
},

,但效果相同.知道我在做什么错吗?回调地狱版本可以使用,但外观丑陋且无法维护.

but with the same effect. Any idea what I'm doing wrong? The callback hell version works, but is just ugly and not maintainable.

戴夫·米汉(Dave Meehan)的答案.必须对其进行稍微的编辑才能使其正常工作.

Answer by Dave Meehan. Had to edit it slightly to make it work.

router.get('/', (req, res) => {
    return Promise.all([
        Account.find(),
        Banner.findOne(),
        Account.findOne({accType: 'Awaiting'}),
    ]).then(([employers, banner, awaiting]) => { // Right here
        if (awaiting != null)
            var areAwaiting = true;
        res.render('admin/', {
            title: 'Admin pannel',
            user: req.user,
            employers: employers,
            areAwaiting: areAwaiting,
            banner: banner,
        });
    }).catch(e => {
        console.error(e)
    });
});

我必须关闭 then 中的数组,将其放入()

I had to close the array in then into ()

推荐答案

这大约很简单,并假设:

This is about as simple as it gets, and assumes:

  1. 您正在使用Express或类似的路由处理程序,并且可以返回承诺而不是使用回调

  1. You are using Express or similar as your route handler, and you can return a promise instead of using the callback

您正在使用Mongoose或与数据库类似的数据库,并且可以返回承诺而不是使用回调.

You are using Mongoose or similar as the DB, and can return a promise instead of using the callback.

检查您的版本以获得Promise支持.

Check your versions for Promise support.

您似乎至少缺少一些Banner的查询参数,并且您需要弄清楚其中的任何一个是否相关,或者如图所示,它们可以并行运行.

You appear to be missing some query parameters for Banner at least, and you need to work out if any of these are dependent or, as illustrated, they can be run in parallel.

router.get('/', (req, res) => {
  return Promise.all([
    Account.find(),
    Banner.findOne(),
    Account.findOne({ accType: 'Awaiting' }),
  ]).then(([ col, banner, doc ]) => {
    res.render('admin/', {
      title: 'Admin pannel',
      user: req.user,
      employers: col,
      areAwaiting: awaiting,
      banner: banner,
    );
  }).catch(e => { console.error(e) });
});

这篇关于避免节点中发生回调地狱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆