如何使用 Node.js return 从一个模块到另一个模块的异步数据库查询结果?
How do I return an asynchronous DB query result from one module to another using Node.js?
我是 Node 的新手,我正在尝试遵循 Udemy API 课程中的模式。 API 的结构是利用路由、控制器和服务模块进行流。数据库查询将 运行 作为服务,它们应该从控制器调用。
我需要 运行 一系列数据库查询来生成一个列表(在这个例子中我只显示了 6 个查询中的 2 个)。我在我的函数中使用 async/await 运行 宁这些。查询工作正常。当我尝试在流程结束时将 return 'batch result'(所有查询的结果)发送给控制器时,我的问题就出现了。我得到 Promise { <pending> }
。我已经尝试了很多东西,但我无法结束从我的控制器模块访问最终结果的承诺——我只能从我的服务模块访问它。
这是我调用函数的控制器模块 (groups.controller.js) 中的代码:
const groupsService = require('../services/groups.service');
exports.propertyList = (req, res, next) => {
const uid = req.body.uid;
const batchResponse = groupsService.batchQuery(uid, res);
console.log(batchResponse);
}
这是我的服务模块 (groups.services.js) 中的代码,我在其中 运行 查询:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
async function batchQuery(uid, res) {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
}
catch(error) {
console.log(error);
res.status(401).send('Server error');
return error;
}
finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
res.status(200).send(batchResponse);
return batchResponse;
}
}
module.exports = {batchQuery};
当我通过 postman 发送 post 时,我得到了预期的查询结果(如下)。但是,如果我将 res
放入我的服务模块,我只能让它工作。
{
"Q1": [
{
"PropertyID": 0
}
],
"Q2": [
{
"SubGroupID": 397
}
]
}
有没有办法结束此模式中的承诺和 return 所需的批处理响应?谢谢。
编辑:添加@traynor 提供的代码更新。
新控制器:
const groupsService = require('../services/groups.service');
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
return res.status(200).send(batchResponse);
} catch(error) {
console.log('Error: ' + error);
return res.status(401).send('Server error');
}
}
新服务:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
function batchQuery(uid) {
return new Promise((resolve, reject) => {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
} catch(error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
})
}
module.exports = {batchQuery};
服务现在return承诺,它也在处理响应而不是控制器。
从服务 到 return,你需要 promisify 服务:return 一个在你获取数据库数据或出错时解决的承诺,然后你还需要等待服务,这它包含在 try/catch
中用于错误处理。
完成后,处理来自控制器的响应:
服务:
function batchQuery(uid) {
return new Promise(async (resolve, reject) => {
var Q1;
var Q2;
//...
try {
//...
} catch (error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: ' + Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
});
控制器:
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
res.status(200).send(batchResponse);
} catch(error) {
return res.status(401).send('Server error');
}
}
我是 Node 的新手,我正在尝试遵循 Udemy API 课程中的模式。 API 的结构是利用路由、控制器和服务模块进行流。数据库查询将 运行 作为服务,它们应该从控制器调用。
我需要 运行 一系列数据库查询来生成一个列表(在这个例子中我只显示了 6 个查询中的 2 个)。我在我的函数中使用 async/await 运行 宁这些。查询工作正常。当我尝试在流程结束时将 return 'batch result'(所有查询的结果)发送给控制器时,我的问题就出现了。我得到 Promise { <pending> }
。我已经尝试了很多东西,但我无法结束从我的控制器模块访问最终结果的承诺——我只能从我的服务模块访问它。
这是我调用函数的控制器模块 (groups.controller.js) 中的代码:
const groupsService = require('../services/groups.service');
exports.propertyList = (req, res, next) => {
const uid = req.body.uid;
const batchResponse = groupsService.batchQuery(uid, res);
console.log(batchResponse);
}
这是我的服务模块 (groups.services.js) 中的代码,我在其中 运行 查询:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
async function batchQuery(uid, res) {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
}
catch(error) {
console.log(error);
res.status(401).send('Server error');
return error;
}
finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
res.status(200).send(batchResponse);
return batchResponse;
}
}
module.exports = {batchQuery};
当我通过 postman 发送 post 时,我得到了预期的查询结果(如下)。但是,如果我将 res
放入我的服务模块,我只能让它工作。
{
"Q1": [
{
"PropertyID": 0
}
],
"Q2": [
{
"SubGroupID": 397
}
]
}
有没有办法结束此模式中的承诺和 return 所需的批处理响应?谢谢。
编辑:添加@traynor 提供的代码更新。
新控制器:
const groupsService = require('../services/groups.service');
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
return res.status(200).send(batchResponse);
} catch(error) {
console.log('Error: ' + error);
return res.status(401).send('Server error');
}
}
新服务:
const mysql = require('mysql2');
const dbAsync = require("../config/db.config");
function batchQuery(uid) {
return new Promise((resolve, reject) => {
var Q1;
var Q2;
var uid = uid * -1;
const pool = mysql.createPool(dbAsync.dbAsync);
const promisePool = pool.promise();
try {
Q1 = await promisePool.query('SELECT PropertyID FROM GroupMembership WHERE GroupID = ?', [uid]);
Q2 = await promisePool.query('SELECT SubGroupID FROM GroupMembership WHERE GroupID = ? AND PropertyID = ?', [uid, 0]);
} catch(error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: '+ Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
})
}
module.exports = {batchQuery};
服务现在return承诺,它也在处理响应而不是控制器。
从服务 到 return,你需要 promisify 服务:return 一个在你获取数据库数据或出错时解决的承诺,然后你还需要等待服务,这它包含在 try/catch
中用于错误处理。
完成后,处理来自控制器的响应:
服务:
function batchQuery(uid) {
return new Promise(async (resolve, reject) => {
var Q1;
var Q2;
//...
try {
//...
} catch (error) {
console.log(error);
reject(error);
} finally {
const batchResponse = {
Q1: Q1[0],
Q2: Q2[0]
}
console.log('Q1: ' + Q1[0][0].PropertyID + ', Q2: ' + Q2[0][0].SubGroupID);
resolve(batchResponse);
}
});
控制器:
exports.propertyList = async (req, res, next) => {
const uid = req.body.uid;
let batchResponse;
try {
batchResponse = await groupsService.batchQuery(uid);
console.log(batchResponse);
res.status(200).send(batchResponse);
} catch(error) {
return res.status(401).send('Server error');
}
}