async.parallel到async await-Node.js

时间:2018-08-08 14:11:05

标签: javascript node.js async-await async.js

我正在使用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)
  })
});

1 个答案:

答案 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.queryrows函数来返回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