UnhandledPromiseRejectionWarning:TypeError:无法读取null的属性“ connect”

时间:2020-02-06 18:57:58

标签: node.js database postgresql typescript connection

我正在尝试连接到我的Postgres DB,只是为了查看是否可以连接,我只有一个条目。但是,每当我尝试连接时,我都会得到连接null错误,为什么会这样?

我的数据库模型


    'use strict';

    import { Pool, Client } from 'pg';

    export default class Postgresql {

        private pool: Pool;

        constructor(private database: string, private host: string, private port: string, private user: string, private password: string) { };
        /* Create a PostgreSQL DB instance */
        connect = (): Promise<Pool> => new Promise((resolve, reject) => {
            this.pool = new Pool({
                database: this.database,
                host: this.host,
                port: Number(this.port),
                user: this.user,
                password: this.password
            });

            this.pool.connect().then(() => {
                resolve(this.pool);
            }).catch(err => reject(err));
        })

    }


我正在导入模型的数据库服务


    import Postgresql from "@root/src/app/models/database.model";

    const databaseService: {

        pool: Postgresql['pool'];
        init: () => Promise<string>;
        execute: (query: string, params: any, next?: any) => Promise<any>;
    } = {
        pool: null,
        init: () =>
            new Promise((resolve, reject) => {
                if (!databaseService.pool) new Postgresql(process.env.DATABASE, process.env.DATABASEHOST,
                    process.env.DATABASEPORT, process.env.DATABASEUSER, process.env.DATABASESECRET)
                    .connect()
                    .then((pool: Postgresql['pool']) => databaseService.pool = pool)
                    .catch((err: Error) => reject(err));
                resolve();
            }),
        async execute(query, params, next?) {
            let client = await this.pool.connect();
            try {
                const result = await client.query(query, params);
                console.log(result);
                next(null, result);
            } catch (e) {
                next(e, null);
            } finally {
                client.release();
            }
        }
    }

    export default databaseService;

从server.js调用数据库

        databaseService.init();
        let query = "SELECT * FROM ?";
        let params = "postgres"
        databaseService.execute(query, params);

和我的env var,我仔细检查了它们的正确性,但无论如何都会出现问题。这是我第一次尝试使用env var连接到数据库,并通过服务进行连接,因此,如果我做错了,请告诉我


    DATABASE=postgres
    DATABASEHOST=localhost
    DATABASEPORT=5432
    DATABASEUSER=postgres
    DATABASESECRET=password


    (node:11020) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'connect' of null
    at Object.<anonymous> (C:\Users\ENGU3002\Documents\Template\src\app\services\database.service.ts:20:38)
    at Generator.next (<anonymous>)
    at C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:106:16)
    at Object.execute (C:\Users\ENGU3002\Documents\Template\src\app\services\database.service.ts:16:24)
    at C:\Users\ENGU3002\Documents\Template\src\app\server.ts:20:25
    at Generator.next (<anonymous>)
    at C:\Users\ENGU3002\Documents\Template\node_modules\tslib\tslib.js:110:75
    at new Promise (<anonymous>)
(node:11020) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:11020) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

1 个答案:

答案 0 :(得分:0)

问题在于您的databaseService.init()是异步的,但您没有等待它,因此对init()返回的承诺解析之前,对databaseService.execute的调用正在发生。

您需要致电

await databaseService.init()

databaseService.init().then(....)

然后在then内进行查询。

与此没有直接关系,但是如果您将一个函数声明为异步,则任何返回的值都将自动包装在一个Promise中,因此您无需显式声明Promise,这将使代码更易于阅读并且更容易发现问题,例如这个。例如,init方法可能类似于:

init: async () => {
    if (!databaseService.pool) {
        databaseService.pool = await new Postgresql(
            process.env.DATABASE,
            process.env.DATABASEHOST,
            process.env.DATABASEPORT,
            process.env.DATABASEUSER,
            process.env.DATABASESECRET
        ).connect()
    }