我试图使代码与您上面的代码相似,但最后我注意到您使用更高级别的 result 对象来传递引用。
在下面的代码中,我没有使用async/await,因为对于这个例子来说这不是完全必要的,因为pool.query 方法需要一个回调。相反,我创建了返回 Promises 的 rows 和 count 函数。然后我将它们与Promise.all 一起使用,这将使两个promise 并行运行,并以与promise 传递给Promise.all 相同的顺序将结果作为数组返回。当pool.query 返回一个promise 时,请参阅下面的示例使用async/await。
router.post('/getDetail', (request, response, next) => {
const id = request.body.id;
const numPerPage = request.body.pSize;
const pageNum = request.body.pIndex;
let query = `select id,name,title,group_desc,unit_code from table1
where id = '${id}'`;
let countQuery = `select count(*) total_item from
(select id,name,title,group_desc,unit_code from table1
where id = '${id}') a`;
const result = {};
Promise.all([
rows(),
count()
])
.then(results => {
// results is an array and the first item is `rows`
response.json(results[0]);
})
.catch(err => {
// handle error
});
function rows() {
return new Promise((resolve, reject) => {
pool.query(
query,
(err, data) => {
if (err) {
return reject(err);
}
result.dataRows = data.rows;
result.numPerPage = numPerPage;
result.pageNum = pageNum;
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.firstItem = (pageNum - 1) * numPerPage + 1;
result.lastItem = (pageNum * numPerPage > result.totalItem) ?
result.totalItem : (pageNum * numPerPage);
resolve(result);
});
});
}
function count() {
return new Promise((resolve, reject) => {
pool.query(
countQuery,
(err, data) => {
if (err) {
return reject(err);
}
result.totalItem = parseInt(data.rows[0].total_item);
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.lastItem = (pageNum * numPerPage > result.totalItem) ?
result.totalItem : (pageNum * numPerPage);
resolve(result);
});
});
}
});
下一个例子展示了使用async/await 假设pool.query 可以返回一个Promise。我还假设对象引用仍将被维护,这就是为什么我在try/catch 的try 部分分配result.rows = results[0]。
router.post('/getDetail', async(request, response, next) => {
const id = request.body.id;
const numPerPage = request.body.pSize;
const pageNum = request.body.pIndex;
let query = `select id,name,title,group_desc,unit_code from table1
where id = '${id}'`;
let countQuery = `select count(*) total_item from
(select id,name,title,group_desc,unit_code from table1
where id = '${id}') a`;
const result = {};
try {
const results = await Promise.all([rows(), count()]);
// results is an array and the first item is `rows`
result.rows = results[0];
} catch (err) {
result.error = err.message;
}
response.json(result.rows);
async function rows() {
const data = await pool.query(query);
result.dataRows = data.rows;
result.numPerPage = numPerPage;
result.pageNum = pageNum;
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.firstItem = (pageNum - 1) * numPerPage + 1;
result.lastItem = (pageNum * numPerPage > result.totalItem)
? result.totalItem
: (pageNum * numPerPage);
return result;
}
async function count() {
const data = await pool.query(countQuery);
result.totalItem = parseInt(data.rows[0].total_item);
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.lastItem = (pageNum * numPerPage > result.totalItem)
? result.totalItem
: (pageNum * numPerPage);
return result;
}
});
我希望这可以帮助您了解如何使用 async/await 进行并行处理。我看到的唯一可能出现在您的代码中的问题是,如果 rows 查询在 count 查询之前返回,因为 totalItem 尚未设置。
编辑:就个人而言,我想我会用 1 个查询而不是 2 个不同的查询来处理这样的逻辑:
router.post('/getDetail', async(request, response, next) => {
const id = request.body.id;
const numPerPage = request.body.pSize;
const pageNum = request.body.pIndex;
let query = `select id,name,title,group_desc,unit_code from table1
where id = '${id}'`;
const result = {};
try {
const data = await pool.query(query);
result.dataRows = data.rows;
result.totalItem = data.rows.length; // data might already have a property for this
result.numPerPage = numPerPage;
result.pageNum = pageNum;
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.firstItem = (pageNum - 1) * numPerPage + 1;
result.lastItem = (pageNum * numPerPage > result.totalItem)
? result.totalItem
: (pageNum * numPerPage);
} catch (err) {
result.error = err.message;
}
response.json(result);
});
编辑 2:在 cmets 中进行了更多讨论后,我认为这个版本会更好。它不使用主 result 对象来提供引用并将基于“计数”的属性移动到 count 函数以允许并行执行:
router.post('/getDetail', async(request, response, next) => {
const id = request.body.id;
const numPerPage = request.body.pSize;
const pageNum = request.body.pIndex;
let query = `select id,name,title,group_desc,unit_code from table1
where id = '${id}'`;
let countQuery = `select count(*) total_item from
(select id,name,title,group_desc,unit_code from table1
where id = '${id}') a`;
let result = { numPerPage, pageNum };
try {
const results = await Promise.all([rows(), count()]);
// this will combine the properties from both results onto the `result` object
result = Object.assign({}, result, ...results);
} catch (err) {
result.error = err.message;
}
response.json(result);
async function rows() {
const data = await pool.query(query);
return { dataRows: data.rows };
}
async function count() {
const data = await pool.query(countQuery);
// redefining result here to be only used in this scope
const result = {};
result.totalItem = parseInt(data.rows[0].total_item);
result.totalPage = Math.ceil(result.totalItem / numPerPage);
result.firstItem = (pageNum - 1) * numPerPage + 1;
result.lastItem = (pageNum * numPerPage > result.totalItem)
? result.totalItem
: (pageNum * numPerPage);
return result;
}
});