我是Promises的新手,所以希望您能为我提供帮助。 我有以下代码:
bcrypt.genSalt(10)
.then((salt) =>{
return bcrypt.hash(newUser.password, salt)
})
.then((hash)=>{
newUser.password = hash;
return mariaDB.pool.getConnection()
})
.then((conn)=>{
conn.beginTransaction()
.then() //here I'm doing some database request
.catch((err)=>{
console.log(err)
return conn.rollback() //where is this Promise handled?
})
})
.catch((err)=>{
res.json({error: err})
})
我收到一个newUser对象,该对象首先传递给bcrypt来加密我的密码。 然后,我需要对我的MariaDB数据库进行事务处理。但是这种“嵌套的承诺”正确吗?有更好的解决方案吗?承诺“ return conn.rollback”在哪里处理?
问候和感谢!
答案 0 :(得分:1)
bcrypt.genSalt(10)
.then((salt) =>{
return bcrypt.hash(newUser.password, salt)
})
.then((hash)=>{
newUser.password = hash;
return mariaDB.pool.getConnection()
})
.then((conn)=>{
return dbops(conn)
})
.catch((err)=>{
res.json({error: err})
})
//添加了新功能db ops
function dbops(conn){
return new Promise(function(resolve,reject){
conn.beginTransaction()
.then((data)=>{
//db stuff
resolve("db stuff done")
}).catch((err)=>{
console.log(err)
conn.rollback()
reject(err)
})
})}
希望这会对您有所帮助。
答案 1 :(得分:1)
像这样简单吗?
bcrypt.genSalt(10)
.then(salt => bcrypt.hash(newUser.password, salt))
.then(hash => {
newUser.password = hash;
return mariaDB.pool.getConnection()
})
.then(conn => {
return conn.beginTransaction()
.then(() => {
// here I'm doing some database request
})
.catch( err => {
conn.rollback();
throw new Error(err); // this error will be cathed on bottom catch
});
})
.catch(err => res.json({error: err}))
答案 2 :(得分:0)
return conn.rollback() //where is this Promise handled?
未处理,这是此代码段的问题。嵌套的Promise应该链接起来,以维持适当的控制流,即从then
和catch
回调返回:
.then((conn)=>{
return conn.beginTransaction()
...
需要嵌套约定,因为conn
回调中应有then
。 async..await
是更方便的处理方式,它可以展平嵌套的Promise:
try {
const salt = await bcrypt.genSalt(10)
const hash = await bcrypt.hash(newUser.password, salt)
newUser.password = hash;
const conn = await mariaDB.pool.getConnection()
try {
conn.beginTransaction()
// ...
} catch (err) {
await conn.rollback()
}
} catch (err) {
res.json({error: err})
}
一件好事是在rollback
之后抛出一个错误,因为很明显这时出错了。
答案 3 :(得分:0)
使用 async / await (通过摆脱所有嵌套的承诺使您的生活更加轻松,稍后再感谢我!)进行重写:
try {
const salt = await bcrypt.genSalt(10);
const hash = await bcrypt.hash(newUser.password, salt);
newUser.password = hash;
const conn = await mariaDB.pool.getConnection();
try {
const transaction = await conn.beginTransaction();
// your db calls
} catch (err) {
console.log(err);
return conn.rollback();
}
} catch (err) {
res.json({error: err})
}
请确保将此块包装在async
函数中。例如,对于自调用功能,请使用:
(async() => {
// the block of code using await ...
})();