如何使用 Node.js、Express.js、MySQL2 和 Promises 在单个请求中正确地进行多个 MySQL 调用
How to correctly make multiple MySQL calls in a single request with Node.js, Express.js, MySQL2, and Promises
当我需要在单个请求中 运行 多个查询时,查看 correct/best/better 在 Node.js/Express.js 应用程序中将 AWAIT 与 MySQL2 结合使用的方法.
在我的应用程序的早期,我从我的数据库配置中创建了一个 Promise 池
const promisePool = db.promise();
然后,根据 POST 请求,我接受 2 个值,我需要验证这两个值是否有效,然后获取返回的 ID 并将它们插入另一个 table。
下面是我的第一次尝试,但我错过了 JS 的同时优点。 (出于演示目的,我过度简化了所有 calls/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 仍然 'feel' 不对,但我需要知道前两个查询有效,否则我会将用户发送到错误页面。
在不牺牲可读性的情况下实现上述结果的更好方法是什么?
首先:两个片段都被破坏了,因为 rows
变量需要在外部声明 if
.
除此之外,你所做的大部分都很好,但这里的大问题是,如果其中任何一个的 length
为 0,你 return 什么都没有。
这真的是您想要的行为吗?如果我调用 /addUserToDepartment
并且你的数据库出现问题,你希望它静默失败吗?
我认为更好的方法是 return 出现问题时适当的错误。理想情况下,你应该只抛出一个异常,(但你使用的是 Express,我不确定它们是否支持捕获异常)。
这是我最后的结果。我添加了捕获,我还作为 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 )
});
});
当我需要在单个请求中 运行 多个查询时,查看 correct/best/better 在 Node.js/Express.js 应用程序中将 AWAIT 与 MySQL2 结合使用的方法.
在我的应用程序的早期,我从我的数据库配置中创建了一个 Promise 池
const promisePool = db.promise();
然后,根据 POST 请求,我接受 2 个值,我需要验证这两个值是否有效,然后获取返回的 ID 并将它们插入另一个 table。
下面是我的第一次尝试,但我错过了 JS 的同时优点。 (出于演示目的,我过度简化了所有 calls/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 仍然 'feel' 不对,但我需要知道前两个查询有效,否则我会将用户发送到错误页面。
在不牺牲可读性的情况下实现上述结果的更好方法是什么?
首先:两个片段都被破坏了,因为 rows
变量需要在外部声明 if
.
除此之外,你所做的大部分都很好,但这里的大问题是,如果其中任何一个的 length
为 0,你 return 什么都没有。
这真的是您想要的行为吗?如果我调用 /addUserToDepartment
并且你的数据库出现问题,你希望它静默失败吗?
我认为更好的方法是 return 出现问题时适当的错误。理想情况下,你应该只抛出一个异常,(但你使用的是 Express,我不确定它们是否支持捕获异常)。
这是我最后的结果。我添加了捕获,我还作为 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 )
});
});