如何使用Node.js、Express.js、MySQL2和Promises在一个请求中正确地进行多个MySQL调用



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

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

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仍然"感觉"不对,但我需要知道前两个查询是有效的,否则我会将用户发送到错误页面。

在不损失太多可读性的情况下,实现上述结果的更好方法是什么?

首先:两个片段都被破坏,因为如果if,则需要在外部声明rows变量。

除此之外,您所做的基本上是好的,但这里的大问题是,如果其中一个的length为0,则不返回任何内容。

这真的是你想要的行为吗?如果我调用/addUserToDepartment,而您的数据库出现问题,您希望此操作以静默方式失败吗?

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

以下是我最后所做的。我添加了catch,我还做了最后一个查询,作为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 )
});
});

最新更新