gpt4 book ai didi

javascript - Bluebird 创建新用户

转载 作者:行者123 更新时间:2023-11-30 15:46:01 25 4
gpt4 key购买 nike

我是 Bluebird 的新手,我正在尝试创建一个新用户,但 reject 函数没有按预期工作。

问题是它为我创建了用户,即使它启动了错误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 });
});
});

谢谢你的建议。

更新

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

最佳答案

TLDR;如果您不希望在错误发生后调用 promise 链中的后续函数,请不要使用 .catch() 或 .then(success , error) 捕获错误。仅在链的末尾捕获以获得整个异步调用链的结果,而不会在错误后产生不需要的调用。

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

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

因此“第一个参数,成功”日志将永远不会触发(因此,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'));

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

关于javascript - Bluebird 创建新用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40062087/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com