Как правильно выполнять несколько вызовов mysql в одном запросе с помощью node.js, express.js, mysql2 и promises

Ищем правильный / лучший / лучший способ использования AWAIT с MySQL2 в приложении Node.js / Express.js, когда мне нужно выполнить несколько запросов в одном запросе.

В начале своего приложения я создаю пул обещаний из конфигурации моей базы данных.

const promisePool = db.promise();

Затем в запросе POST я принимаю 2 значения, оба из которых мне нужно проверить, действительны, а затем беру возвращенные идентификаторы и ВСТАВЛЯЮ их в другую таблицу.

Ниже была моя первая попытка, но я упускаю из виду одновременное совершенство 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 в конце все еще «не кажется правильным», но мне нужно знать, что первые два запроса действительны, иначе я отправлю пользователя на страницу с ошибкой.

Что было бы лучшим способом достичь вышеуказанного результата без слишком большой потери читабельности?

0
0
473
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

во-первых: оба фрагмента не работают, так как переменная rows должна быть объявлена ​​снаружи, если if.

В остальном то, что вы делаете, в основном нормально, но большая проблема здесь в том, что если length любого из них равен 0, вы ничего не вернете.

Вы действительно хотите такого поведения? Если я позвоню /addUserToDepartment и возникнет проблема с вашей базой данных, вы хотите, чтобы это происходило без уведомления?

Я думаю, что лучший подход - возвращать соответствующие ошибки, когда что-то идет не так. В идеале вы должны просто выбросить исключение (но вы используете Express, и я не уверен, поддерживают ли они перехват исключений).

Спасибо, что нашли время ответить. Я вернулся к нему и добавил уловки, поскольку Node.js без них был бы недоволен.

Andy Jarrett 07.11.2018 17:14
Ответ принят как подходящий

Вот что я сделал в итоге. Я добавил уловки, а также сделал свой последний запрос как часть цепочки 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 )
    });
  });

Другие вопросы по теме