如何简化在使用相同参数的路由内创建回调函数的方法?

时间:2018-08-25 09:56:33

标签: node.js express asynchronous

我一直坚持在节点/表达式中创建可重复使用相同参数的包装回调函数的最佳方法。

问题是验证需要使用与回调相同的参数。有没有一种方法可以简化此过程?我已经在堆栈和谷歌上寻找了,但是找不到答案。我不想在实际通话中再写两次req,res。我知道第一个要求,下一个要求被传递到回调中,但是像这样编写它仍然感觉很奇怪。感觉上肯定有更好的方法,但是我只是不知道那是什么。

这里是情况:

function verifyCaptcha(req, res, next, callback) {

    let captchaResponse = req.body.captchaResponse;

    let captchaSecret = "it's a secret";

    let captchaURL = "https://www.google.com/recaptcha/api/siteverify?"
    + "secret=" + encodeURIComponent(captchaSecret) + "&"
    + "response=" + encodeURIComponent(captchaResponse) + "&"
    + "remoteip" + encodeURIComponent(req.connection.remoteAddress);

    // request is ASYNC, that's why I need the callback
    request(captchaURL, function(error, response, body) {
        callback(req, res, next);
        return;
    });
};


router.post('/login', function(req, res, next) {

    // example call INSIDE a route (here's the problem b/c params are repeated in the call
    verifyCaptcha(req, res, next, function(req, res, next){
        // do stuff
    });

};

2 个答案:

答案 0 :(得分:1)

承诺应该避免回调地狱。所有流行的基于回调的库都有相应的约定,request-promise的名称为request。可以使用async..await以类似同步的方式编写:

const request = require('request-promise');

async function verifyCaptcha(req, res) {
    let captchaResponse = req.body.captchaResponse;

    let captchaSecret = "it's a secret";

    let captchaURL = "https://www.google.com/recaptcha/api/siteverify?"
    + "secret=" + encodeURIComponent(captchaSecret) + "&"
    + "response=" + encodeURIComponent(captchaResponse) + "&"
    + "remoteip" + encodeURIComponent(req.connection.remoteAddress);

    const result = await request(captchaURL);
    ...
};


router.post('/login', async function(req, res, next) {
    try {
        await verifyCaptcha(req, res);
    } catch (err) {
        next(err);
    }
};

this question中所述,Express不原生支持promise,所有拒绝应由开发人员处理,async中间件/处理程序功能主体应包裹在try..catch中。 / p>

答案 1 :(得分:0)

根据快速文档,您可以通过简单地将中间件添加到路由调用中来链接中间件。

http://expressjs.com/en/4x/api.html#app.use

可以执行以下操作:

function verifyCaptcha(req, res, next) {
    let captchaUrl = ...

    request(captchaUrl, function(error, response, body) {
        if (error) res.sendStatus(403)
        next()
    }
}

router.post('/login', verifyCaptcha, function(req, res, next) {
    // this will only run if verifyCaptcha calls next()
}

最终结果在实践中更具可读性。