数据库查询Promise未解析并阻塞请求

问题描述 投票:0回答:1

祝所有志同道合或知识渊博的人美好的一天。

我正在尝试在 Web 服务器中实现 H2 数据库连接(数据库在服务器模式下运行,因此我可以通过 TCP/IP 建立多个连接),我发现自己每次都处于相同的状态,该函数被调用并且它以 pending 状态返回承诺,我留下一个等待,最终只是一直走下去,而没有从查询中得到答案。

我使用的堆栈是

  • node(12.11.0,别怪我,这是客户的要求)
  • expressjs,因为客户端只需要 3 个端点
  • H2 数据库已存在于我的客户端服务器上用于身份验证
  • SQL Server,里面有业务的核心数据,认证完之后我就用。

函数的调用

    userModel.getUsers();

函数getUsers

    try {
        const connection = await h2.getInstance().getConnection();
        console.log('Connection established');

        return connection.query('SELECT * FROM USERS');
    } catch (error) {
        console.error(error);
        throw error;
    }

H2 连接 类,您将看到我正在使用 pg 库来处理连接,因为它可以通过 TCP/IP 完成,但也尝试使用 jdbc 获得相同的结果。

    class H2Connection {
        // Use a private static field to store the instance
        static #instance = null;

        // Use a private constructor to prevent direct instantiation
        constructor() {
            this.connection = new pg.Client(h2Conf);
            this.connection.connect();
        }

        static getInstance() {
            // If the instance does not exist, create a new one
            if (H2Connection.#instance == null) {
                H2Connection.#instance = new H2Connection();
            }
            // Return the instance
            return H2Connection.#instance;
        }

        // Use a method to get the connection
        getConnection() {
           return this.connection;
        }
    }

希望有人能帮助我解决这个问题。

尝试过:

  • 将回调的处理更改为 Promise,反之亦然。
  • 尝试在函数调用上使用await来接收已解决的承诺,但从未成功。
  • 调试代码以检查是否有任何可能无法捕获的错误,但它最终在 Web 服务器的等待请求内部进程中来回。
  • 尝试解析承诺并返回函数内部局部变量所需的值,但在承诺/回调的范围之外。

预期:

  • 在调用服务后进行任何类型的日志记录,这是我在调用函数时未使用await时得到的,但它总是为稍后我在逻辑中检查的变量分配未定义的值。
  • 尝试从 then-catch 的使用中获取日志记录,但也从未在函数内部或外部获取任何日志记录。
  • 查询结果,数组或json格式。
node.js express promise database-connection h2
1个回答
0
投票

看起来你的连接工厂可以简化,我无法重现完整的场景,但是

connection.query()
需要先有一个与
this.connection.connect();
连接的数据库实例,这是一个Promise,但你不等待它在致电
return connection.query('SELECT * FROM USERS');
之前完成。

您可以做的是使用单例设计模式构建可重用的连接实例,并在整个项目中全局使用它。实例化单例后的一件重要事情是在运行查询之前调用一个方法来设置它/等待连接建立,例如

waitConnection()
,因为禁止的异步构造函数的设计存在限制,我建议看一下。我提出的解决方案是这样的:

database-driver.js

const pg = require("pg");

const connectionString = "..."

class H2ConnectionFactory {
    constructor(h2ConnectionString) {
        this.connection = new pg.Client(h2ConnectionString);
    }

    async waitConnection() {
        await this.connection.connect();
    }

    getConnection() {
        return this.connection;
    }
}

export const dbSingleton = new H2ConnectionFactory(connectionString);

main.js

import { dbSingleton } from "./database-driver";

async function getAnyData() {
    try {
        const connection = dbSingleton.getConnection();
        console.warn('query rows result:', (await connection.query('SELECT NOW()')).rows);
    } catch (error) {
        console.error(error);
        throw error;
    }
};

async function main() {
    await dbSingleton.waitConnection();
    console.log('Connection established');

    getAnyData();
}

main()

所以代码的顺序是:

    1. 确保数据库连接成功;
    1. 之后重用该连接执行任何查询;

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.