我正在使用express-promise-router 在来自node.js 的查询调用中实现async/await。有时,当我需要获取表的数据时,我使用 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)
})
});
最佳答案
我试图使代码与上面的代码相似,但我最后注意到您使用了更高级别的 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
部分分配 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:经过评论中的更多讨论,我认为这个版本会更好。它不使用主 result
对象来提供引用,并将基于“count”的属性移动到 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;
}
});
关于javascript - async.parallel 与 async wait - Node.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51748818/