2017-04-24 13 views
0

私はES6を使ってNode.jsアプリケーションクラスでビルドしています。私は、DBクラスを作成したいので、私は次のようでした:最初に私はプライベート変数を保存しようとしていますNode.js ES6クラスのプライベートストレージ

"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接続では、次のソースコードで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(); 
}) 
+0

'this'として使用することができます。

これを解決するための良い方法はDbの新しい、完全に初期化されたインスタンスを返す静的な非同期メソッドを持つことですコールバックの中で 'undefined 'です。解決方法については、[コールバックの中の正しい「this」にアクセスする方法」(https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback)を参照してください。 。しかし、全体的なアプローチは疑わしいようです。 'parse'が非同期であると仮定すると、呼び出し側は初期化の完了をどのように知るでしょうか? –

+0

呼び出し元は、私が成功なしに約束を実装しようとしたことを知っているので、編集のようにコールバック関数を使用します。 –

+0

そして、コールバックが呼び出された時点で、 'ini.parse'は*まだ*完了していません。あなたは基本的に不完全なオブジェクトをコールバックに渡しています。 –

答えて

0

thisがコールバックの内側undefinedあり、それはあなたがそのエラーを取得するため、Dbのインスタンスを参照しませれます。それを解決する方法についてはHow to access the correct `this` inside a callback?をご覧ください。

ただし、ここではさらに大きな問題があります。コンストラクタ内で非同期操作を実行しています。つまり、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(); 
});