【问题标题】:Stuck in a express callback hell陷入快速回调地狱
【发布时间】:2018-03-01 22:28:12
【问题描述】:

成功发送电子邮件后,我无法取消请求。发送邮件后如何正确返回?这可能是一个回调地狱,但我不知道如何解决它。

我尝试将一些回报放在不同的部分,但没有奏效。

const router        = require('express').Router();
const nodemailer    = require('nodemailer');
const emailExistence= require('email-existence');

module.exports = router;

// Send email when user has forgotten his/her password
router.post('/forgetPass', (req, res, next) => {
    if(!req.body.email){
        next(new Error("Email is required."));
        return;
    }

    emailExistence.check(req.body.email, function(err,res){

        if(err || !res){
            next(new Error("The email does'nt exist."));
            return;
        }else{
            let transporter = nodemailer.createTransport({
                service: 'gmail',
                auth: {
                    user: 'myemail@gmail.com',
                    pass: 'mypassword'
                }
            });

            let mailOptions = {
                from:       'myemail@gmail.com',
                to:          req.body.email,
                subject:    'Link for setting a new password',
                html:       'Set a new password'
                text:       'email text'    
            };


            transporter.sendMail(mailOptions, function(error, info){
                if (error) {
                    next(new Error("Error in sending email."));
                    return;
                }

                res.json(Object.assign(req.base, {
                    message: "The email has been sent successfully.",
                    data: info
                }));
                return;

            });
        }
    });
});

【问题讨论】:

  • 您在emailExistence.check 中做了什么数据库检查??
  • @iam-batman,它检查电子邮件是否存在(当电子邮件存在时 res 为 true [表示电子邮件有效],当电子邮件不存在时 res 为 false)。这可以正常工作,当电子邮件不存在时我会收到错误消息。但问题是电子邮件已成功发送。请求并没有就此结束。
  • 发送邮件后能否登录info
  • @iam-batman,不,它不返回 json。我也试过 return res.json(Object.assign...。但它仍然不起作用
  • 我的意思是这个`transporter.sendMail(mailOptions, function(error, info){console.log(info)}`

标签: node.js express callback promise nodemailer


【解决方案1】:

将响应字段设置为成功发送后,调用 next() 作为最后一步,以便下一个中间件获取请求并发送回响应。所以基本上:

...
res.json(yourResponse);
next();
...

或者,如果这是最后一个中间件,则将响应发送回客户端:

res.send(yourResponse);

【讨论】:

    【解决方案2】:

    我就是这样解决的。 emailExistence 不允许我使用 Promise,所以我使用 email-ckeck 代替它:

    const router        = require('express').Router();
    const nodemailer    = require('nodemailer');
    const emailExistence= require('email-existence');
    var emailCheck      = require('email-check');
    
    module.exports = router;
    
    router.post('/forgetPass', (req, res, next) => {
        if(!req.body.email){
            next(new Error("Email is required."));
            return;
        }
    
        // Check the req.body.email with email pattern regex
        var patt = new RegExp (process.env.EMAIL_PATTERN__REGEX),
            isEmail = patt.test(req.body.email);    
    
        if(!isEmail){
            next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
            return;
        } 
    
        return emailCheck(req.body.email)
            .then(function(result){
                let transporter = nodemailer.createTransport({
                    service: 'gmail',
                    auth: {
                        user: process.env.EMAIL,
                        pass: process.env.EMAILPASSWORD
                    }
                });
    
                let mailOptions = {
                    from:       process.env.EMAIL,
                    to:         req.body.email,
                    subject:    'Link for setting a new password',
                    html:       'Set a new password from <a href="http://www.example.com/newpass">this link</a>.'    
                };
    
                return transporter.sendMail(mailOptions)
                    .then(function (result2) {
                                res.status(200).json(Object.assign(req.base, {
                                    message: "The email has been sent successfully.",
                                    data: null
                                }));
                                return;
                            },
                            function(error2){
                                next(new Error("Error in sending email."));
                                    return;
                            });
            },
            function(error) {
                next(new Error("The email does'nt seem to be a valid email. If you are sure about your email validity contact the website admin."));
                return;
            });
    });
    

    【讨论】:

      猜你喜欢
      • 2017-04-06
      • 2017-05-08
      • 1970-01-01
      • 1970-01-01
      • 2013-08-08
      • 2018-06-26
      • 2017-01-01
      • 2015-04-05
      • 2015-01-05
      相关资源
      最近更新 更多