[英]How to handle kind of nested Promises in NodeJS
我是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”在哪里處理?
問候和謝謝!
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)
})
})}
希望這會幫助你。
這樣簡單:
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}))
return conn.rollback() //where is this Promise handled?
未處理,這是此代碼段的問題。 嵌套的Promise應該鏈接起來,以保持適當的控制流,即then
返回並catch
回調:
.then((conn)=>{
return conn.beginTransaction()
...
需要嵌套的promise,因為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
后拋出一個錯誤,因為很明顯這時出錯了。
用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 {
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 ...
})();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.