2017-08-08 6 views
0

デフォルトの関数とプロパティのリストをエクスポートするモジュール(関数もあります)を記述したいと思います。 基本的には、このモジュールの意志は、この使用、消費者側が可能:Module.export 'default'関数

let db_connection = fake_database_connection_instance() 
let db = require('./db.js')(db_connection) 
db.find({id:1}) 

ので、デフォルトの機能はモジュールだけに、データベース接続のインスタンスを渡す必要があります。 これが機能していないコード

module.exports = { 
    //init should go away and replaced by a 'default' function when this module is called 
    init: function (connection) { 
     this.connection= connection; 
     return this; 
    }, 
    find: function (query) { 
     return new Promise(function (resolve, reject) { 
      this.connection.find(query, function (err, docs) { 
       if (err) { 
        return reject(err); 
       } 
       return resolve(docs); 
      }); 
     }); 
    } 
} 

である私はnewキーワード(消費者側)を避けたいので、私は私が知っているものをthisを、削除する必要があります。ここでの問題は、require('./db.js')()とその他の関数で呼び出されるデフォルト関数をエクスポートする方法2:

  • require('./db.js').find()
  • 接続インスタンスをデフォルト関数からfind()に渡すにはどうすればよいですか?

EDIT @Igor Raush ES6クラスのソリューション、次の私はこれを書いたが、それでもdb is not defined

class DB { 
    constructor(db) { 
     this.db = db; 
    } 
    find(query) { 
     return new Promise((resolve, reject) => { 
      this.db.find(query, function (err, docs) { 
       if (err) { 
        return reject(err); 
       } 
       return resolve(docs); 
      }); 
     }); 
    } 
} 
+0

更新されたコードでは、 'this' **は' Promise'関数によって作成されたスコープに対して** DBのインスタンスではなく**参照されます。別のスコープで使用するには 'DB.this'を覚えておく必要があります。 – alexmac

+0

それはあまり「上品ではない」(OOPの意味で:))。とにかくありがとうと – alfredopacino

+0

はい、構文的な砂糖をES6に追加しても、それはちょうどjavascript :) – alexmac

答えて

1

1つのオプションは、クラスを作成して、インスタンスのファクトリ関数をエクスポートすることです。

// db.js 
function DB(connection) { 
    this.connection = connection; 
} 

DB.prototype.find = function find(query) { 
    let connection = this.connection; 
    // ... 
} 

// export instance factory function 
module.exports = function (connection) { return new DB(connection); }; 

か、あなたはES6環境にいる場合、

// db.js 
class DB { 
    constructor(connection) { 
     this.connection = connection; 
    } 

    find(query) { 
     let connection = this.connection; 
     // ... 
    } 
} 

// export instance factory function 
module.exports = connection => new DB(connection); 

あなたはシングルトンパターン(一つだけDBを強制したいなら、あなたは

let db = require('./db')(db_connection); 
db.find({ id: 1 }); 

を行うことができますインスタンスが存在する可能性があります)、モジュールローカルインスタンスを遅延して作成し、その後の呼び出しで参照を返します。

let _instance = null; 
module.exports = connection => { 
    // return existing instance, or create a new one 
    return _instance || (_instance = new DB(connection)); 
} 
+0

'find()'で 'let connection = this.connection'を使う理由を聞いてもいいですか? Promiseで新しい変数を宣言せずに 'this.connection'を直接参照しようとしましたが、この例ではコンテキストが変わるところでは動作しません。 – alfredopacino

+0

@alfredopacino、promise executor関数内の 'this'は、あなたが期待する' DB'インスタンスではなく、グローバルオブジェクトを参照します。私が行ったように 'connection'オブジェクトへのローカル参照を保持するか、または' this'のレキシカルスコープを保持するために約束の実行者として矢印関数を使用することができます。この場合、 'DB'インスタンスを参照しますエグゼクティブの中に。 –

+0

私は間違ったことをしましたか?私の編集 – alfredopacino

3

あなたはmodule.exports上のデフォルトの関数を定義し、ストア接続に外部変数_connを使用することができます。

let _conn; 

module.exports = (connection) => { 
    _conn = connection; 
}; 

その後、の機能をに追加できます10対象:

module.exports.find = (query) => { 
    return new Promise(function(resolve, reject) { 
    _conn.find(query, function(err, docs) { 
     if (err) { 
     return reject(err); 
     } 
     resolve(docs); 
    }); 
    }); 
} 
+0

"初期化"関数を呼び出すのを忘れると、モジュールのローカル_connが他のすべてで定義されなくなります。エクスポートされた関数。 –

+0

@IgorRaush同じ問題があなたの例にあります:)必要なパラメータを渡すのを忘れてしまった場合、どのモジュールも期待通りの動作をしません。 – alexmac

+0

'find()'などの関数をまったくエクスポートしませんが、 'require( './ db')の代わりに' let db = require( './ db' )(db_connection) 'の場合、間違ったオブジェクトで作業していることが明らかです(' db.find'は未定義です)。いずれにしても、私はあなたの実装を使用しますが、処理する前に '_conn'の存在を宣言する各エクスポート関数にチェックを入れます。 –

関連する問題