【问题标题】:NodeJS class with Promise in method方法中带有 Promise 的 NodeJS 类
【发布时间】:2018-05-08 14:13:16
【问题描述】:

我从 NodeJS 开始,已经写了几天的代码。现在我正在创建一个新的 Winston Transport,以便使用 MSSQL 或 OracleDB 作为日志目的地。

我决定创建一个 DB 类来管理与 DB 的连接、插入等。

我的想法是在构造函数中声明一个连接(null),然后有方法来创建连接、插入等

但是,由于连接是异步的,并且 Winston 传输调用 log 方法,我需要创建连接,进行插入并关闭(或保持打开连接)。

所以我选择了这个:

class db {

    constructor(){
        this.connection = null;
    }

    connect(){

        return new Promise(function(resolve, reject){
            if (this.connection == null){
                if (config.Logging.DB.type == 'mssql'){

                    const dbOptions = {
                        user: config.Logging.DB.user,
                        password: config.Logging.DB.password,
                        server: config.Logging.DB.mssql.server,
                        database: config.Logging.DB.mssql.database,
                        options: {
                            encrypt: config.Logging.DB.encrypt
                        }
                    };

                    this.connection = new mssql.ConnectionPool(dbOptions, err => {
                        if (err) reject('Can\'t establish a DB connection.');
                        this.connection.connect(err => {
                            if (err) reject(err);
                            resolve();
                        });
                    });

                }
            }else{
                resolve();
            }
        });
    }

    insert(query){
        if (config.Logging.DB.type == 'mssql'){
            this.connection.request().query(query, err => {
                console.log(err);
            });
        }
    }

}

我的想法是在启动应用程序时创建一个 db 类实例,然后使用该打开的连接进行任何插入(每次 winston 调用 log 方法),如下所示:

const db = require('./functions/db'); const db_instance = new db();

//Custom DB transport
class DBTransport extends Transport {
    constructor(opts){
        super(opts);
        //db.getConnection();
    }

    log(info, callback) {

        //write
        db_instance.connect().then(()=>{
            db_instance.insert(`insert into logs (message) values ("${info.message}")`);
        }).catch((err)=>{
            console.log(err);
        });

        callback();
    }

}

但这根本不起作用。首先,我在 db 类连接方法中遇到错误,我试图在 promise 中访问“this.connection”,但我无法访问。

而且我还想保持连接打开,因为 winston 可能会多次调用 log 方法(我有一个进程会调用 log 方法超过 5K 次)。

我确实尝试过使用一些可用的 winston-mssql 传输...但它们都已更新,并且不适用于当前版本的 winston。

谁能帮忙?

【问题讨论】:

    标签: node.js


    【解决方案1】:

    你需要在你的连接函数之外保存承诺,并像这样每次都返回那个记忆的承诺:

    class DBTransport {
      connect() {
        if (!this._pool) {
          // Memoize (cache) the connection so you don't have to remake it every time
          this._pool = new Promise(function(resolve, reject) {
            const pool = new mssql.ConnectionPool(dbOptions);
            return pool.connect().then(function() {
              return pool;
            });
          });
        }
        return this._pool;
      }
      insert(query) {
        // Always refetch your connection
        return this.connect().then(function(pool) {
          return pool.request().query(query);
        })
      }
    }
    

    【讨论】:

    • 试过了,但我收到“UnhandledPromiseRejectionWarning: Unhandled Promise Rejection.”
    • 添加一些错误处理,我注意到插入时出现错误:连接已关闭。很奇怪,因为我按照您上面的建议打开了连接。
    • 嗯 2 在每个函数中返回?因为它到处都是我的错误:(
    • 返回值在各自的函数中。
    • 我将示例更新为不使用箭头函数,以便您更好地阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-28
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2015-12-02
    • 1970-01-01
    相关资源
    最近更新 更多