我正在使用express-promise-router在来自node.js的查询调用中实现异步/等待。有时,当我需要获取表的数据时,我使用async.parallel来获取数据以及计数作为单独的数据并将其合并。我在这里使用回调。我该如何继续使用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 = {};
async.parallel({
rows: (cb) => {
pool.query(
query,
(err, data) => {
if (!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)
}
cb(err, result)
})
},
count: (cb) => pool.query(
countQuery,
(err, data) => {
if (!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)
}
cb(err, result);
})
}, (err, result) => {
if (err) {
result.error = err.message;
}
response.json(result.rows)
})
});
答案 0 :(得分:2)
我试图使代码与上面的代码相似,但是最后我注意到您正在使用更高级别的import matplotlib.pyplot as plt
labels = [r"$1.$", r"$1.5$", r"$2.$"]
ticks = [1., 1.5, 2.]
plt.set_xticks(ticks)
plt.set_xticklabels(labels)
对象来传递引用。
在下面的代码中,我没有使用result
,因为在本示例中这并不是完全必要的,因为async/await
方法采用了回调。相反,我创建了pool.query
和rows
函数来返回Promises。然后,将它们与count
一起使用,这将使两个promise并行运行,并以将promise传递到Promise.all
的顺序将结果作为数组返回。当Promise.all
改为返回诺言时,请参见使用async/await
的示例。
pool.query
下一个示例显示使用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
可以返回Promise。我还假设仍将保留对象引用,这就是为什么要在pool.query
的{{1}}部分分配result.rows = results[0]
。
try
我希望这可以帮助您了解如何使用try/catch
进行并行处理。我认为您的代码中可能会出现的唯一问题是,由于尚未设置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
查询之前返回。
编辑:就我个人而言,我认为我将使用1个查询而不是2个不同的查询来处理这样的逻辑:
count
编辑2:在评论中进行了更多讨论之后,我认为此版本会更好。它不使用主totalItem
对象提供引用,也不将基于“计数”的属性移动到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);
});
函数中以允许并行执行:
result