[英]How do I return an asynchronous DB query result from one module to another using Node.js?
I'm new to Node, and I'm trying to follow a pattern from a Udemy API course.我是 Node 的新手,我正在尝试遵循 Udemy API 课程中的模式。 The API is structured to utilize route, controller and service modules for flow.
API的结构是利用路由,controller和业务模块进行流量。 Database queries are to be run as services and they are supposed to be called from controllers.
数据库查询将作为服务运行,并且应该从控制器调用。
I need to run a series of DB queries to generate a list (I'm showing only 2 of 6 queries in this example).我需要运行一系列数据库查询来生成一个列表(在此示例中,我只显示了 6 个查询中的 2 个)。 I am running these using async/await in my function. The queries are working fine.
我在我的 function 中使用 async/await 运行这些查询。查询工作正常。 My problem occurs when I try to return the 'batch result' (the result of all the queries) to the controller at the end of the process.
当我尝试在过程结束时将“批处理结果”(所有查询的结果)返回到 controller 时,我的问题就出现了。 I get
Promise { <pending> }
.我得到
Promise { <pending> }
。 I have tried many things, but I cannot end the promise to access the final result from my controller module--I can only access it from my service module.我已经尝试了很多东西,但我无法结束 promise 以从我的 controller 模块访问最终结果——我只能从我的服务模块访问它。
Here is my code from my controller module (groups.controller.js) where I call my function:这是我的 controller 模块 (groups.controller.js) 中的代码,我将其称为 function:
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);
}
And here is my code from my service module (groups.services.js) where I run the queries:这是我运行查询的服务模块 (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};
When I send a post via postman, I get the expected query result (below).当我通过 postman 发送帖子时,我得到了预期的查询结果(如下)。 However, I can only get this to work if I put my
res
in my service module.但是,如果我将
res
放入我的服务模块,我只能让它工作。
{
"Q1": [
{
"PropertyID": 0
}
],
"Q2": [
{
"SubGroupID": 397
}
]
}
Is there a way to end the promise in this pattern and return the desired batch response?有没有办法以这种模式结束 promise 并返回所需的批处理响应? Thank you.
谢谢你。
EDIT: Adding the code updates provided by @traynor.编辑:添加@traynor 提供的代码更新。
New controller:新 controller:
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');
}
}
New service:新服务:
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};
the service is now returning a promise, and it's also handling response instead of controller.该服务现在返回 promise,并且它还在处理响应而不是 controller。
to return from service, you need to promisify service: return a promise which resolves when you get db data, or on error, and then you also need to await the service, which it's wrapped in try/catch
for error handling.要从服务返回,您需要承诺服务:返回一个 promise,它会在您获取数据库数据或出错时解析,然后您还需要等待该服务,它被包装在
try/catch
中以进行错误处理。
once it's all done, handle response from the controller:完成后,处理来自 controller 的响应:
service:服务:
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);
}
});
controller: controller:
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');
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.