无法读取未定义mysql的属性'typeCast'

Col*_*ole 3 javascript mysql promise typescript es6-promise

我有代码:

import { createConnection } from 'mysql';
import { promisify } from 'util';

export default class Database {
    static instance: Database;

    query;
    db;

    constructor(user, password, database, host) {
        Database.instance = this;

        this.db = createConnection({ user, password, database, host });
        this.db.connect();
        this.query = promisify(this.db.query);
    }

    async getUser(id: number, filter: string = null) {
        return this.query('SELECT * FROM users WHERE id = ' + id)
        .then((err, res, fields) => {
            return res[0];
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

以及将ID传递到的快速路线getUser

执行此代码后,我得到了这个堆栈。

(node:16544) [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.
(node:16544) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'typeCast' of undefined
    at Database.query (<project>\node_modules\mysql\lib\Connection.js:199:34)
    at Database.query (internal/util.js:232:30)
    at Database.getUser (<project>\lib\structures\Database.js:13:21)
    at get (<project>\lib\api\routes\user.js:5:33)
    at Layer.handle [as handle_request] (<project>\node_modules\express\lib\router\layer.js:95:5)
    at next (<project>\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (<project>\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (<project>\node_modules\express\lib\router\layer.js:95:5)
    at <project>\node_modules\express\lib\router\index.js:281:22
    at param (<project>\node_modules\express\lib\router\index.js:354:14)
(node:16544) 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: 6)
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

Jak*_*ake 5

我发现了针对同一问题的不同解决方案。我没有用此工具测试您的代码,但是在我看来,查看mysql模块的源代码this已不再正确。绑定query到db对象可以为我修复它。您的情况如下所示: this.query = promisify(this.db.query.bind(this.db));


ran*_*shu 2

Promisify(...)返回一个承诺。所以你应该await像这样使用:await Promisify(...)

解决方案是:

1)this.query = promisify(...)this.db.connect();你的 constructor

2)你的Database类和getUser函数应该如下所示:

export default class Database {
    static instance: Database;

    static async getInstance(user?, password?, database?, host?) {
        // all arguments above are optional

        if(!Database.instance){
            const connection = createConnection({ user, password, database, host });
            await connection.connect();
            const dbQuery = await promisify(this.promisify(connection.query));
            Database.instance = {
                query: dbQuery 
            }
            return Database.instance;
        }
        return Database.instance;
    }

    static getUser(id: number, filter: string = null) {
        return Database.instance.query('SELECT * FROM users WHERE id = ' + id)
        .then((err, res, fields) => {
            return res[0];
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

使用方法:

然后,无论您需要什么:

async getUser(){
    let database = await Database.getInstance(); // or Database.getInstance(user, password ...)  to first initialize and then get the instance.
    return database.getUser(1234, filter);
}
Run Code Online (Sandbox Code Playgroud)