蓝鸟创建新用户
Bluebird create new user
我是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'));
将在控制台中打印错误堆栈跟踪而不仅仅是消息。
- 如何在节点中为用户创建某种警报
- 如何为在客户端检查其密码的用户创建登录页面
- 如何防止用户创建重复ID
- 如何在完整日历中筛选出用户创建的事件
- 使用java和html基于当前用户创建重定向链接
- 在jquery或jquery移动中,如何将用户创建的链接传递到用户创建的按钮?我所说的用户是指最终用户,而不是我
- 用户创建的应用程序的安全性
- 为多个用户创建自动低分辨率和高分辨率pdf,png与inDesign
- 如何为用户创建唯一的网址
- 如何在我的网页上为iPhone用户创建一个注释,说明有一个应用程序
- 当用户创建新帖子时,张贴到墙上时出错
- 为不同的用户创建一个常规页面
- 如何为不同的用户创建Opencart模块
- Express js会话——仅为登录用户创建
- 根据用户创建文本字段's在JavaScript函数中的输入
- 从用户创建的选择字段中获取所有选定项目的值
- 在数据库中保存用户创建的javascript是否安全
- 如何为用户创建带有构建选项的流星JS包
- 如何在Meteor中验证服务器上的用户创建
- 如何获取用户文本输入用户创建输入的值,jQuery