蓝鸟创建新用户

Bluebird create new user

本文关键字:用户 创建 新用户 蓝鸟      更新时间:2023-09-26

我是Bluebird的新手,我正在尝试创建一个新用户,但reject功能不像预期的那样工作。

问题是,它创建了我的user,即使它启动错误There nickname is already in use

我在下面粘贴我的代码。

User.js

var User = require('../models/user');
var Promise = require('bluebird');
module.exports = {
  validateFields: function (nickname) {
    return new Promise(function (response, reject) {
      if (!nickname) {
        reject('You must provide the nickname');
      } else if (nickname.length < 4 || nickname.length > 20) {
        reject('The nickname must be longer than 4 and shorter than 20 characters');
      } else {
        nickname = nickname.trim();
        User.findOne({ "nickname": nickname }).exec()
          .then(function (user) {
            if (user) {
              reject('There nickname is already in use');
            } else {
              response();
            }
          }, function (err) {
            reject('There is an error trying to verify the nickname');
          });
      }
    });
  },
  registerUser: function (user_id, nickname) {
    return new User({ user_id: user_id, nickname: nickname }).save();
  }
};

register.js

var validator = require('validator');
var Promise   = require('bluebird');
var Account = require('../../models/account');
module.exports = {
  validateFields: function (email, password) {
    return new Promise(function (response, reject) {
      if (!email) {
        reject('You must provide the email');
      } else if (!password) {
        reject('You must provide the password');
      } else if (email.length < 6) {
        reject('The email is too short');
      } else if (email.length > 40) {
        reject('The email is too long');
      } else if (!validator.isEmail(email)) {
        reject('The email is not valid');
      } else {
        Account.findOne({ email: email }).exec()
          .then(function (account) {
            if (account) {
              reject('There is already an email');
            } else {
              console.log(account);
              response();
            }
          }, function (err) {
            reject('There is an error trying to verify the email');
          });
      }
    });
  },
  registerAccount: function (email, password) {
    return new Account({ email: email, password: password }).save();
  }
};

routes.js

var Promise  = require('bluebird');
var user     = require('./routes/user');
var account  = require('./routes/auth/register');
router.post('/register', function (req, res, next) {
  account.validateFields(req.body.email, req.body.password)
    .then(function () {
      return user.validateFields(req.body.nickname);
    }, function (err) {
      return res.status(400).json({ msg: err });
    })
    .then(function () {
      req.body.email = req.body.email.trim();
      req.body.password = req.body.password.trim();
      console.log('bien');
      return account.registerAccount(req.body.email, req.body.password);
    }, function (err) {
      console.log('mal');
      return res.status(400).json({ msg: 'There was an error trying to save the email' });
    })
    .then(function (data) {
      return user.registerUser(data, req.body.nickname);
    }, function (err) {
      return res.status(400).json({ msg: 'There was an error trying to save the user' });
    })
    .then(function () {
      return res.status(200);
    }, function (err) {
      console.log(err);
      return res.status(400).json({ msg: err });
    })
    .catch(function (err) {
      console.log('catch');
      return res.status(400).json({ msg: err });
    });
});

谢谢你的建议。

只是为了澄清每个从承诺开始并正在寻找最佳实践的人,我想这个链接是有帮助的。

;如果你不想在错误发生后调用承诺链中的后续函数,不要使用.catch()或.then(success, error)捕获错误。只在异步调用链的末尾进行Catch,以获得整个异步调用链的结果,而不会在出现错误后进行不必要的调用。

好的,让我们想象一个函数只返回一个被拒绝的承诺:

function fakeForbiddenAsyncOperation(){
    return new Promise(function(resolve , reject){
        return reject('This operation is forbidden');
    });
}

然后,一个像

这样的承诺链:
fakeForbiddenAsyncOperation().then(
function(){
    console.log('first parameter, success');
},
function(err ){
    console.log('second parameter, failure: ' + err);
})
.then(function(){
    console.log('This log is called, because the previous error was catched in the second then() lambda');
})
.catch(console.log);

将让console.log '这个日志被称为…'运行,因为错误正在处理中。输出将是:

第二个参数,failure:禁止该操作

这个日志被调用,因为之前的错误在第二个then() lambda

中被捕获。

你想在你的代码中做什么,如果在验证中有一个先前的错误,阻止用户被创建,更像:

fakeForbiddenAsyncOperation().then(
function(){
    console.log('first parameter, success');
})
.then(function(){
    console.log('This log is called');
} , function(err){
    console.log('There was an err: ' + err);
    console.log('this is called at the end, and the previous "this log is called" log wasn''t fired because there was an unhandled rejection');
});

哪个输出是:

There was an err: Error: This operation is forbidden

这个在最后被调用,而前面的这个日志被调用。未触发日志,因为有未处理的拒绝

因此,"第一个参数,成功"日志将永远不会触发(因此,如果有先前的错误,User.create()函数或任何其他您不想执行的操作也不会触发)。

还有两个小问题你可能想要处理:

Bluebird文档建议使用。catch()而不是。then(success, failure):

forbiddenAsyncOperation().then(
function(){
    console.log('first parameter, success');
})
.then(function(){
    console.log('This log is called');
})
.catch(function(){
    console.log('this is called at the end, and the previous "this log is called" log wasn''t fired because there was an unhandled rejection');
});

将像前面的例子一样。

同样,最好拒绝错误而不是字符串:

 reject(new Error('The nickname must be longer than 4 and shorter than 20 characters'));

将在控制台中打印错误堆栈跟踪而不仅仅是消息。