Как обрабатывать вложенные Обещания в NodeJS - PullRequest
0 голосов
/ 14 ноября 2018

Я относительно новичок в Обещаниях, поэтому надеюсь, что вы мне поможете.У меня есть следующий код:

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.Но верен ли этот вид «вложенных Обещаний»?Есть ли лучшее решение?Где обрабатывается обещание «вернуть conn.rollback»?

Привет и спасибо!

Ответы [ 4 ]

0 голосов
/ 14 ноября 2018

Переписать с 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 ...
})();
0 голосов
/ 14 ноября 2018
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)
        })
     })}

Надеюсь, это поможет вам.

0 голосов
/ 14 ноября 2018

Сделайте это просто так:

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}))
0 голосов
/ 14 ноября 2018
return conn.rollback() //where is this Promise handled?

не обрабатывается, это проблема с этим фрагментом.Вложенные обещания должны быть объединены в цепочку для поддержания правильного потока управления, то есть возвращены из обратных вызовов then и catch:

.then((conn)=>{
    return conn.beginTransaction()
    ...

Требуется вложенное обещание, потому что conn должно быть доступно в обратных вызовах then,Более удобный способ справиться с этим - 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 {
        conn.beginTransaction()
        // ...
    } catch (err) {
        await conn.rollback()
    }
} catch (err) {
    res.json({error: err})
}

Хорошо было бы сбросить ошибку после rollback, поскольку ясно, что в этом случае что-то пошло не такточка.

...