蓝鸟创建新用户
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 });
});
});
谢谢指教。
更新
只是为了澄清每个从承诺开始并正在寻找最佳实践的人,我想 this link 会有所帮助。
TLDR;如果您不希望在错误发生后调用 promise 链中的后续函数,请不要使用 .catch() 或 .then(success , error) 捕获错误。仅在链的末尾捕获以获得整个异步调用链的结果,而不会在错误后出现不需要的调用。
好吧,让我们想象一个函数,它只是 returns 一个被拒绝的承诺:
function fakeForbiddenAsyncOperation(){
return new Promise(function(resolve , reject){
return reject('This operation is forbidden');
});
}
然后,Promise 链如下:
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'this log is called...'变成运行,因为错误正在处理中。输出将是:
second parameter, failure: This operation is forbidden
This log is called, because the previous error was catched in the second 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
this is called at the end, and the previous "this log is called" log wasnt fired because there was an unhandled rejection
所以 'first parameter, success' 日志将永远不会触发(因此,User.create() 函数,或任何其他你不想执行的操作,如果有以前的错误,不会也是)。
您可能还需要处理 2 个小问题:
Bluebird documentation 建议使用 .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');
});
将像前面的示例一样运行。
此外,is better to reject errors instead of strings:
reject(new Error('The nickname must be longer than 4 and shorter than 20 characters'));
将打印错误堆栈跟踪,而不仅仅是控制台中的一条消息。
我是 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 });
});
});
谢谢指教。
更新
只是为了澄清每个从承诺开始并正在寻找最佳实践的人,我想 this link 会有所帮助。
TLDR;如果您不希望在错误发生后调用 promise 链中的后续函数,请不要使用 .catch() 或 .then(success , error) 捕获错误。仅在链的末尾捕获以获得整个异步调用链的结果,而不会在错误后出现不需要的调用。
好吧,让我们想象一个函数,它只是 returns 一个被拒绝的承诺:
function fakeForbiddenAsyncOperation(){
return new Promise(function(resolve , reject){
return reject('This operation is forbidden');
});
}
然后,Promise 链如下:
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'this log is called...'变成运行,因为错误正在处理中。输出将是:
second parameter, failure: This operation is forbidden
This log is called, because the previous error was catched in the second 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
this is called at the end, and the previous "this log is called" log wasnt fired because there was an unhandled rejection
所以 'first parameter, success' 日志将永远不会触发(因此,User.create() 函数,或任何其他你不想执行的操作,如果有以前的错误,不会也是)。
您可能还需要处理 2 个小问题:
Bluebird documentation 建议使用 .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');
});
将像前面的示例一样运行。
此外,is better to reject errors instead of strings:
reject(new Error('The nickname must be longer than 4 and shorter than 20 characters'));
将打印错误堆栈跟踪,而不仅仅是控制台中的一条消息。