如何在server.js中导入原生SQL文件 用Promise.all异步执行合并响应
实现步骤
1. 目录结构调整
把所有原生.sql文件单独存放到固定目录,完全保留编辑器的SQL语法高亮支持,不需要在JS代码中硬拼接SQL字符串,参考结构:
项目根目录 ├── sql/ # 存放所有原生SQL文件 │ ├── comments.sql # 你提供的评论查询SQL │ ├── posts.sql # 其余两个业务SQL文件 │ └── users.sql ├── db/ │ ├── connection.js # 数据库连接实例 │ └── queries.js # 封装统一的查询方法 └── server.js # 服务入口文件
其中sql/comments.sql直接存你写的查询语句即可,不需要做任何转义或修改:
SELECT b.id ,a.parent_id -- original post id ,b.post_id ,b.user_id ,b.comment ,c.first_name ,c.last_name ,c.user_name ,c.profile_pic ,c.status ,c.profile_status ,c.creation_datetime ,a.creation_datetime as post_at FROM tester.posts_master a LEFT JOIN tester.post_comment_master b on (a.parent_id = b.parent_id) LEFT JOIN tester.user_master c on (c.user_id = b.user_id)
2. 封装独立查询函数
在db/queries.js中,实现SQL文件读取逻辑,给每个SQL文件封装独立的Promise风格查询方法,统一导出:
const fs = require('fs/promises'); const path = require('path'); // 导入你自己初始化好的数据库连接实例 const connection = require('./connection'); // 通用SQL文件加载工具 const loadSQL = (fileName) => { const sqlPath = path.join(__dirname, '../sql', fileName); return fs.readFile(sqlPath, 'utf8'); }; // 封装评论查询 const getComments = async () => { const sql = await loadSQL('comments.sql'); return new Promise((resolve, reject) => { connection.query(sql, (err, results) => err ? reject(err) : resolve(results)); }); }; // 封装帖子查询(对应posts.sql) const getPosts = async () => { const sql = await loadSQL('posts.sql'); return new Promise((resolve, reject) => { connection.query(sql, (err, results) => err ? reject(err) : resolve(results)); }); }; // 封装用户查询(对应users.sql) const getUsers = async () => { const sql = await loadSQL('users.sql'); return new Promise((resolve, reject) => { connection.query(sql, (err, results) => err ? reject(err) : resolve(results)); }); }; module.exports = { getComments, getPosts, getUsers };
如果你使用的是
mysql2等自带Promise API的数据库驱动,可以直接用connection.promise().query(sql)写法,不需要手动包装Promise。
3. 服务端整合执行、统一返回
在server.js中导入封装好的三个查询方法,用Promise.all并行执行所有查询,把结果整合到同一个JSON响应中返回,不会产生多个独立响应。以Express服务为例:
const express = require('express'); const { getComments, getPosts, getUsers } = require('./db/queries'); const app = express(); app.get('/api/full-data', async (req, res) => { try { // 并行执行三个查询,结果顺序和传入数组顺序严格对应 const [comments, posts, users] = await Promise.all([ getComments(), getPosts(), getUsers() ]); // 整合为单一JSON响应返回 res.status(200).json({ success: true, data: { comments, posts, users } }); } catch (err) { // 任意一个查询报错都会统一捕获,返回错误响应 res.status(500).json({ success: false, message: '数据查询失败', error: err.message }); } }); app.listen(3000, () => console.log('服务启动在3000端口'));
注意事项
- 独立存放
.sql文件的方式不会破坏编辑器的SQL语法校验、高亮、提示能力,不需要在JS中动态拼接SQL Promise.all会等待所有查询完成后才继续往下执行,只要有一个查询报错就会直接进入异常分支,适合多数据源并行拉取的场景- 解构拿到的三个结果顺序和传入
Promise.all的方法顺序完全一致,不会出现结果错位问题
内容的提问来源于stack exchange,提问作者Riziki
相关产品推荐
相关产品推荐

