簡體   English   中英

如何處理NodeJS中的嵌套Promises

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM