Javascript 如何处理NodeJS中的嵌套承诺

Javascript 如何处理NodeJS中的嵌套承诺,javascript,node.js,callback,promise,nested,Javascript,Node.js,Callback,Promise,Nested,我对承诺还比较陌生,所以我希望你能帮助我。 我有以下代码: bcrypt.genSalt(10) .then((salt) =>{ return bcrypt.hash(newUser.password, salt) }) .then((hash)=>{ newUser.password = hash; return mariaDB.pool.getConnection() }) .then((

我对承诺还比较陌生,所以我希望你能帮助我。 我有以下代码:

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() //where is this Promise handled?
未处理,这就是此代码段的问题所在。嵌套的承诺应该链接起来,以保持适当的控制流,即从
然后
catch
回调返回:

.then((conn)=>{
    return conn.beginTransaction()
    ...
嵌套承诺是必需的,因为
conn
应该在
然后
回调中可用。处理此问题的更方便的方法是
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
之后重新显示一个错误,因为很明显在这一点上出了问题

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})
})
未处理,这就是此代码段的问题所在。嵌套的承诺应该链接起来,以保持适当的控制流,即从
然后
catch
回调返回:

.then((conn)=>{
    return conn.beginTransaction()
    ...
嵌套承诺是必需的,因为
conn
应该在
然后
回调中可用。处理此问题的更方便的方法是
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
之后重新显示一个错误,因为很明显在这一点上出了问题

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)
        })
     })}
希望这对你有帮助

//添加了新功能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}))
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})
}

这样做很简单:

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}))
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/await(通过摆脱所有嵌套的承诺,让您的生活变得更轻松,稍后感谢我!)进行重写时,将如下所示:

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}))
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 ...
})();

使用async/await(通过摆脱所有嵌套的承诺,让您的生活变得更轻松,稍后感谢我!)进行重写时,将如下所示:

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}))
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 ...
})();

用async/await重构它会更具可读性,代码看起来会像sync,但它的行为会像async。像伪代码?如何将其更改为async和await?@mcAngular2您可以在此处尝试使用async/await。让生活更轻松!用async/await重构它会更具可读性,代码看起来会像sync,但它的行为会像async。像伪代码?如何将其更改为async和await?@mcAngular2您可以在此处尝试使用async/await。让生活更轻松!我怎样才能改变这一点,起诉async并等待?类似这样的事情。希望这有帮助,只需将上面的代码包装在异步函数yourFuncName(){};关于async/await的更多信息我如何使用async和await来更改此设置?类似这样的内容。希望这有帮助,只需将上面的代码包装在异步函数yourFuncName(){};有关async/await
新承诺的更多信息是承诺构造反模式。已经有了一个承诺,不需要再创造一个新的。它也不考虑来自
rollback()
的承诺。
newpromise
是承诺构造反模式。已经有了一个承诺,不需要再创造一个新的。它也不考虑
rollback()
的承诺。