【问题标题】:How to correctly make multiple MySQL calls in a single request with Node.js, Express.js, MySQL2, and Promises如何使用 Node.js、Express.js、MySQL2 和 Promises 在单个请求中正确进行多个 MySQL 调用
【发布时间】:2019-04-04 13:30:17
【问题描述】:

当我需要在单个请求中运行多个查询时,查看在 Node.js/Express.js 应用程序中使用 AWAIT 和 MySQL2 的正确/最佳/更好方法。

在我的应用程序的早期,我从我的数据库配置中创建了一个 Promise 池

const promisePool = db.promise();

然后,在 POST 请求中,我接受 2 个值,我需要验证这两个值都是有效的,然后将返回的 ID 插入到另一个表中。

以下是我的第一次尝试,但我错过了 JS 的并发优点。 (出于演示目的,我过度简化了所有调用/SQL),

app.post('/addUserToDepartment', async (req, res) => {
    // Get the POST variables
    let email = 'example@example.com';
    let departmentname = 'sales';
    let insertParams = [];

    // Need to check if Department ID is even valid
    const [departments] = await promisePool.query( "SELECT ? AS deptid", [departmentname] );

    // Need to check if Email address is valid
    const [user] = await promisePool.query( "SELECT ? AS userid", [email] );

    // This would normall be an INSERT or UPDATE statement
    if(departments.length && user.length){
        const [rows] = await promisePool.query( "SELECT ? AS passedDeptId,? AS passedUserid", [departments[0].deptid, user[0].userid] );
    }

    res.send( rows )
}

这是我的第二次尝试,现在结束承诺。

app.post('/addUserToDepartment', async (req, res) => {
    // Get the POST variables
    let email = 'example@example.com';
    let departmentname = 'sales';
    let insertParams = [];

    // Need to check if Department ID is even valid
    let [[departments],[user]] =
    await Promise.all([
        promisePool.query( "SELECT ? AS deptid", [departmentname] ),
        promisePool.query( "SELECT ? AS userid", [email] )
    ])

    // This would normall be an INSERT or UPDATE statement
    if(departments.length && user.length){
        let [rows] = await promisePool.query( "SELECT ? AS passedDeptId,? AS passedUserid", [departments[0].deptid, user[0].userid] );
    }

    res.send( rows )
}

最后的 IF 仍然“感觉”不正确,但我需要知道前两个查询是有效的,否则我会将用户发送到错误页面。

在不牺牲可读性的情况下实现上述结果的更好方法是什么?

【问题讨论】:

    标签: node.js express promise async-await node-mysql2


    【解决方案1】:

    这就是我最后的结果。我添加了捕获,我还将最后一个查询作为 Promise.all() 链的一部分。

      app.get('/test2', async (req, res) => {
        // Get the POST variables
        let email = 'example@example.com';
        let departmentname = 'sales';
        let insertParams = [];
        let rtn = {
          status : '',
          errors : [],
          values : []
        }
        console.clear();
        // Need to check if Department ID is even valid
    
        let arrayOfPromises = [
          promisePool.query( "SELECT ? AS did", [departmentname] ),
          promisePool.query( "SELECT ? AS uid", [email] )
        ]
        await Promise.all(arrayOfPromises)
        .then( ([d,u] ) => {
          // Get the  values back from the queries
          let did = d[0][0].did;
          let uid = u[0][0].uid;
          let arrayOfValues = [did,uid];
    
          // Check the values
          if(did == 'sales'){
            rtn.values.push( did );
          } else{
            rtn.errors.push( `${did} is not a valid department`);
          }
          if(uid == 'example@example.com'){
            rtn.values.push( uid );
          } else{
            rtn.errors.push( `${did} is not a valid department`);
          }
    
          if( rtn.errors.length === 0){
            return arrayOfValues;
          } else{
            return Promise.reject();
          }
        })
        .then( async ( val ) => {
          // By this point everything is ok
          let [rows] = await promisePool.query( "SELECT ? AS passedDeptId,? AS passedUserid", val );
          res.send( rtn )
        })
        .catch((err) => {
          console.error(err)
          rtn.status = 'APPLICATION ERROR';
          rtn.errors.push( err.message);
          res.send( rtn )
        });
      });
    

    【讨论】:

      【解决方案2】:

      首先:两个 sn-ps 都被破坏了,因为如果 if 需要在外部声明 rows 变量。

      除此之外,您所做的大部分工作都很好,但这里的大问题是,如果 length 中的任何一个为 0,您什么都不会返回。

      这真的是你想要的行为吗?如果我致电/addUserToDepartment 并且您的数据库出现问题,您是否希望它静默失败?

      我认为更好的方法是在出现问题时返回适当的错误。理想情况下,您应该只抛出一个异常,(但您使用的是 Express,我不确定它们是否支持捕获异常)。

      【讨论】:

      • 感谢您花时间回答。我确实回到了它并添加了捕获,因为没有它们 Node.js 会不高兴。
      猜你喜欢
      • 1970-01-01
      • 2017-09-14
      • 2016-03-29
      • 2019-04-19
      • 2017-04-10
      • 2019-07-08
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      相关资源
      最近更新 更多