简体   繁体   English

如何使用 Node.js 将异步数据库查询结果从一个模块返回到另一个模块?

[英]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.

相关问题 使用node.js,如何写入一个MySQL DB并从另一个读取? - Using node.js, how can I write to one MySQL DB and read from another? 如何返回\\从不查询mysql的node.js模块检索结果? - how to return \ retrieve a result from node.js module that does query to mysql? 如何从包含来自另一个应用程序的数据库查询的 Node.js 函数获取返回值 - How to get the return value from Node.js function which contains DB query from another application 我们如何不使用Ajax将sql查询结果数据返回到node.js中的调用者函数? - how do we return sql query result data to caller function in node.js without using ajax? 我如何在 node.js 和 mysql 中对 map 一个查询到另一个 - How do I map one query to another in node.js and mysql 使用node.js执行查询后返回MySQL结果 - Return MySQL result after query execution using node.js 如何多次循环MYSQL查询并从node.js中的每个循环查询返回数据? - How do I loop a MYSQL query multiple times and return the data from each looped query in node.js? 如何返回 MySQL 查询的回调并推送到 Node.js 中的数组? - How do I return callback of MySQL query and push to an array in Node.js? 如何为 Node.js 返回多个 sql 表 - How do I return more than one sql table for Node.js 如何从Node.js中的mySQL查询返回JSON对象 - How to return a JSON object from a mySQL query in node.js
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM