【问题标题】:Node.js ES6 class private storageNode.js ES6 类私有存储
【发布时间】:2017-09-21 04:27:12
【问题描述】:

我正在使用 ES6 通过 Node.js 应用程序类构建。我想创建一个 db 类,所以我做了以下操作:

"use strict"

var ini = require('node-ini');
var mysql = require('mysql');
let _db = new WeakMap();

// Class de base pour la base de donnée 
class Db{
    constructor () {
        ini.parse('../config/settings.ini', function(err,data){
            if(err) {
                console.log(err);
                return;
            } else {
                _db.set(this, mysql.createConnection({
                    host     : data.database_MYSQL.host,
                    user     : data.database_MYSQL.username,
                    password : data.database_MYSQL.password,
                    database : data.database_MYSQL.schema
                }));
            }
        });
    }
}

module.exports = Db;

这是我第一次尝试存储私有变量,我在网上寻找解决方案。我找到了我尝试实施的 Weakmap 解决方案。但 MySQL 连接不会将其与以下源代码一起存储。我有这个输出:

_db.set(this, mysql.createConnection({
                    ^
TypeError: Invalid value used as weak map key
    at WeakMap.set (native)
    at D:\supervision\application\class\db.js:15:21
    at D:\supervision\application\node_modules\node-ini\node-ini.js:168:12
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)

那么怎么处理呢?

编辑:

这是调用者如何知道它何时被初始化的:

var db;

function instantiateDb(callback){
        db = new db_connector();
        callback(db);
}

instantiateDb(function(db){
    db.connectDatabase();
})

【问题讨论】:

  • this 在回调中是undefined。请参阅How to access the correct this inside a callback? 获取解决方案。然而,整体方法似乎值得怀疑。假设parse是异步的,调用者怎么知道初始化完成的时间?
  • 调用者知道我试图实现承诺但没有成功,所以我使用回调函数,就像在编辑中一样
  • 在调用回调的那一刻,ini.parse还没有完成。您基本上是将一个不完整的对象传递给回调。

标签: mysql node.js ecmascript-6 es6-class


【解决方案1】:

this 是回调内部的undefined,它不是指的是Db 的实例,因此您会收到该错误。看看How to access the correct `this` inside a callback? 了解如何解决这个问题。

但是,这里有一个更大的问题:您正在构造函数中执行异步操作。这意味着任何想要使用Db 实例的人都无法知道它何时会被完全初始化。

解决此问题的更好方法是使用一个静态异步方法,该方法返回一个新的、完全初始化的 Db 实例:

class Db {
  static get() {
    return new Promise((resolve, reject) => {
      ini.parse('../config/settings.ini', function(err,data){
        if (err) {
          reject(err);
        } else {
          resolve(new Db(data));
        }
      });
    });
  }

  constructor (data) {
    _db.set(this, mysql.createConnection({
      host     : data.database_MYSQL.host,
      user     : data.database_MYSQL.username,
      password : data.database_MYSQL.password,
      database : data.database_MYSQL.schema
    }));
  }
}

然后可以用作

Db.get().then(db => {
  db.connectDatabase();
});

【讨论】:

    猜你喜欢
    • 2017-07-29
    • 2014-04-05
    • 2019-02-04
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多