【问题标题】:Code is being executed even after return statement is there?即使有return语句,代码也正在执行?
【发布时间】:2018-06-30 02:50:55
【问题描述】:

我正在使用 mongoose 唯一验证器来使我的用户模型中的姓名和电子邮件唯一。当我尝试在数据库中保存一个重复的用户时,它给了我一个错误,这是好的,但即使在返回响应之后,return 语句下面的代码正在执行,我得到一个错误,说 “错误:发送后无法设置标题。” 这是我的代码。

用户.js:

var mongoose = require("mongoose")
var uniqueValidator = require("mongoose-unique-validator");
var crypto = require("crypto");
var userSchema = new mongoose.Schema(
    {
        name: {
            type: String,
            required: [true, 'cant be blank'],
            unique: true,
            match: [/^[a-zA-Z0-9]+$/, "is invalid"],
            index: true
        },
        email: {
            type: String,
            unique: true,
            required: [true, 'cant be blank'],
            index: true
        },
        salt: String,
        password_hash: String
    }, { timestamps: true });

userSchema.plugin(uniqueValidator, { message: "already taken" });

userSchema.methods.setPassword = function (password) {
    this.salt = crypto.randomBytes(15).toString('hex');
    //console.log(this.salt);
    this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');

    //console.log(this.hash);
}
userSchema.methods.checkPassword = function (password) {
    var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
    return this.hash == hash;
}

var User = module.exports = mongoose.model("User", userSchema);

路由器.js

//route for Signup


router.get("/signup", function (req, res) {
    res.render('signup.html');
});
router.post('/signup', function (req, res) {
    var name = req.body.name;
    var email = req.body.email;
    var password = req.body.password;
    var verify = req.body.verify;
    if (!name || !email || !password || !verify || password != verify) {
        var passwordError;
        if (password != verify)
            passwordError = 'Password are not matching';
        res.render('signup.html', { 'Error': 'Invalid Details', 'name': name, 'email': email, 'passwordError': passwordError });
        return;
    }

    var newUser = User(
        {
            name: name,
            email: email

        });
    newUser.setPassword(password);
    newUser.save(function (err) {
        if (err) {
            //console.log("Database Error:%s" , err);
            console.log(err);
            // Even after using return statement the code below this 
            // statement is being executed . I dont know why?
            return res.status(500).send({ success: false, message: 'User already exists' });
        }

    });
    console.log("here");

    req.session.user = newUser;
    console.log(newUser);
    res.redirect('/newpost');
});

注意:我没有添加 router.js 文件的完整代码。 我知道解决这个问题的方法是在 else 语句中添加剩余的代码。但我不明白为什么会出现这个错误。

我在控制台中得到的错误是:

{ _id: 5a645473ae051e159a62f080,
  name: 'dipen',
  email: 'dipenbhatt12@gmail.com',
  salt: '2f3e989389918507aaea0915b59852' }
  { [ValidationError: User validation failed: name: already taken]
  errors: 
  { name: 
  { [ValidatorError: already taken]
    message: 'already taken',
    name: 'ValidatorError',
    properties: [Object],
    kind: 'unique',
    path: 'name',
    value: 'dipen',
    reason: undefined,
    '$isValidatorError': true } },
  _message: 'User validation failed',
  name: 'ValidationError' }

events.js:141
      throw er; // Unhandled 'error' event
  ^

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/home/asmodeus/Programs/HelloWorld/node_modules/express/lib/response.js:767:10)
at ServerResponse.send (/home/asmodeus/Programs/HelloWorld/node_modules/express/lib/response.js:170:12)
at ServerResponse.json (/home/asmodeus/Programs/HelloWorld/node_modules/express/lib/response.js:267:15)
at ServerResponse.send (/home/asmodeus/Programs/HelloWorld/node_modules/express/lib/response.js:158:21)
at /home/asmodeus/Programs/HelloWorld/router.js:141:27
at /home/asmodeus/Programs/HelloWorld/node_modules/mongoose/lib/model.js:3907:16
at /home/asmodeus/Programs/HelloWorld/node_modules/mongoose/lib/model.js:334:16
at /home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:246:48
at next (/home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:167:27)
at Kareem.execPre.Kareem.execPost.callback [as execPost] (/home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:217:3)
at _handleWrapError (/home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:245:21)
at /home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:271:14
at _next (/home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:94:14)
at Immediate._onImmediate (/home/asmodeus/Programs/HelloWorld/node_modules/kareem/index.js:420:34)
at processImmediate [as _immediateCallback] (timers.js:383:17)

【问题讨论】:

  • 仔细查看return 的位置。它从save() 回调中返回。它不影响save所在的功能。
  • @SergioTulentsev 那么,一旦我得到那个错误,我应该如何从整个函数中返回。

标签: javascript node.js mongodb express


【解决方案1】:

只需使用 save 返回 Promise 的事实:

  //Make the route async
 router.post('/signup' , async function(req,res){

   //validate user input
   const { name, email, password, verify } = req.body;
   if(!name || !email || !password || !verify) 
      return res.json({ error:"Wrong data"});
   }

   //create a new user
   const user = User({ name, email });

   // asynchronously save it to db, catch all errors
   try {
     await user.save();
     //return valid response
     return res.json({success: true});
   } catch(e){
     return res.json({error:"dupe"});
  }
});

您的代码不起作用,因为您根本无法从回调中返回。这将返回调用回调的内部函数。

【讨论】:

  • 默认情况下,路由的回调不是异步的。我不清楚等待,这里使用等待会暂停 /signup 的回调函数,直到保存完成。
  • @dipen 是的。 await 将等待用户被保存,然后继续执行代码。如果保存失败,promise 被拒绝,await 会抛出,代码进入 catch 块。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 2015-07-11
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多