express+MySQL异步执行多条查询语句

express+MySQL异步执行多条查询语句

并行处理

在写后端接口时,有个需求,需要返回一年四个季度每个季度24小时的统计数据,但是数据库中没有季度这个字段,也没有小时的字段,只有一个时间,时间是完整的,年月日,小时都有,所以可以从时间这个字段中取出季度和小时,但是得执行四个查询语句,如下

const sqls = [
    "select substr(sgfssj, 12, 2) as xs, sum(swrs) as swrs from accident  where sgfssj >= ? and sgfssj < ? and substr(sgfssj, 6, 2) in ('01', '02', '03') group by substr(sgfssj, 12, 2) order by substr(sgfssj, 12, 2) asc",
    "select substr(sgfssj, 12, 2) as xs, sum(swrs) as swrs from accident  where sgfssj >= ? and sgfssj < ? and substr(sgfssj, 6, 2) in ('04', '05', '06') group by substr(sgfssj, 12, 2) order by substr(sgfssj, 12, 2) asc",
    "select substr(sgfssj, 12, 2) as xs, sum(swrs) as swrs from accident  where sgfssj >= ? and sgfssj < ? and substr(sgfssj, 6, 2) in ('07', '08', '09') group by substr(sgfssj, 12, 2) order by substr(sgfssj, 12, 2) asc",
    "select substr(sgfssj, 12, 2) as xs, sum(swrs) as swrs from accident  where sgfssj >= ? and sgfssj < ? and substr(sgfssj, 6, 2) in ('10', '11', '12') group by substr(sgfssj, 12, 2) order by substr(sgfssj, 12, 2) asc",
  ];

上面的查询语句还是比较复杂的,但逻辑比较清楚,就是从时间中取出月份和小时,月份作为筛选条件,时间作为聚合依据和排序值

要执行4条sql语句,但是express中数据库查询是异步的,也就是说,没法通过分段把数据push到最终要的结果中,如果简单push,那么这个结果中永远都是空值。

比如下面的写法:

const data = []
for(let i = 0; i < sqls.length; i++){
    db.query(sqls[i], [s1, s2], (err, results) => {
        data.push(results)
    })
}

上面是个示意

这么写得到的data永远是空数组,原因就是db.query()是异步函数,执行push的时候,results根本就还没有得到

网上搜了一下解决方案,有的说用定时器,有的说用async和await,都比较麻烦,记录一下我最后的处理方案

const data = {};
  async.parallel(
    [
      (parallel_done) => {
        db.query(sqls[0], [startTime, endTime], (err, results) => {
          if (err) return parallel_done(err);
          data.first = results;
          parallel_done();
        });
      },
      (parallel_done) => {
        db.query(sqls[1], [startTime, endTime], (err, results) => {
          if (err) return parallel_done(err);
          data.second = results;
          parallel_done();
        });
      },
    ],
    (err) => {
      if (err) console.log(err)
      db.end();
      res.json(data)
    }
  );

上面的代码也不是完整的,err前应该还有两个parallel_done

简单解释一下,async.parallel是一种并行方式,适用于处理每一个进程,进程之间没有依赖关系,中途某个流程出错就会退出。

2023年7月12日更新

异步处理

随着对node异步编程理解的加深,尝试了一下异步的解决方案,看起来更容易让人接受,记录一下
直接上代码

exports.test = (req, res) => {
	const execute1 = () => {
		return new promise(resolve => {
			db.query(sql[0],[startTime, endTime], (err, results) => {
				if (err) return res.send({ status: 400, message: err });
        		resolve(results);
			})
		})
	}

	const execute2 = () => {
		return new promise(resolve => {
			db.query(sql[1],[startTime, endTime], (err, results) => {
				if (err) return res.send({ status: 400, message: err });
        		resolve(results);
			})
		})
	}

	async function getData(){
		const res1 = await execute1()
		const res2 = await execute2()
		const data = [res1, res2]
		res.send({data})
	}

	getData()
}

以上代码是在csdn的富文本编辑器中纯手写的,没有编译测试,可能会有些bug,可参考这篇博客

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

栀椩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值