2017-05-18 24 views
-3

私はMongoというラッパークラスを作成しようとしています。私がinsert()内でgetCollection()を呼び出すと、 'TypeError:this.getCollectionが関数ではありません'というメッセージが表示されます。同じクラスの別のメソッドからjavascriptクラスメソッドを呼び出す

const mongoClient = require('mongodb').MongoClient; 
const connectionString = process.env.MONGODB_CONNECTION_STRING; 
const mongoOptions = { 
    connectTimeoutMS: 500, 
    autoReconnect: true 
}; 

function Mongo(dbName, collectionName) { 
    this.dbName = dbName; 
    this.collectionName = collectionName; 
    this.db = null; 
    this.collectionCache = {}; 

    this.getDB = function() { 
     return new Promise(function (resolve, reject) { 
      if (this.db == null) { 
       mongoClient.connect(connectionString, mongoOptions, function (err, db) { 
        if (err) reject(err); 
        this.db = db.db(this.dbName); 
        resolve(this.db); 
       }); 
      } else { 
       resolve(this.db); 
      } 
     }); 
    }; 

    this.getCollection = function() { 
     return new Promise(function (resolve, reject) { 
      if (this.collectionName in this.collectionCache) { 
       resolve(this.collectionCache[this.collectionName]);     
      } else { 
       getDB().then(function(db) { 
        db.collection(this.collectionName, function (err, collection) { 
         if (err) reject(err); 
         this.collectionCache[this.collectionName] = collection; 
         resolve(collection);      
        }); 
       }, function (err) { 
        reject(err); 
       }); 
      } 
     }); 
    }; 

    this.insert = function(docs) { 
     return new Promise(function (resolve, reject) { 
      this.getCollection().then(function(collection) { 
       collection.insert(docs, function(err, results) { 
        if (err) reject(err); 
        resolve(results); 
       }); 
      }); 
     }, function (err) { 
      reject(err); 
     }); 
    } 
} 


module.exports = Mongo; 

このクラスがインスタンス化され、挿入メソッドが呼び出される方法。

const assert = require('assert'); 
const Mongo = require('../data/mongo'); 

describe('MongoTest', function() { 
    it('TestInsert', function() { 
     var mongo = new Mongo('testdb', 'humans'); 

     var testDoc = { 
      _id: 1100, 
      name: 'tommy', 
      tags: ['cool', 'interesting'] 
     }; 

     mongo.insert(testDoc).then(function(result){ 
      assert.equal(result._id, 1100); 
     }); 
    }) 
}) 

答えて

1

は、thisは、もはやそれはあなたがPromiseにパラメータとして渡されてきたコールバック関数を指し、Mongoオブジェクトを参照しません。

これを修正する方法はたくさんあります。ここではいくつかは以下のとおりです。

オブジェクトへの参照を維持する:

コンテキストをバインド
this.insert = function(docs) { 
    var self = this; 
    return new Promise(function (resolve, reject) { 
     self.getCollection().then(function(collection) { 
      collection.insert(docs, function(err, results) { 
       if (err) reject(err); 
       resolve(results); 
      }); 
     }); 
    }, function (err) { 
     reject(err); 
    }); 
} 

this.insert = function(docs) { 
    var callbackFunction = function (resolve, reject) { 
     this.getCollection().then(function(collection) { 
      collection.insert(docs, function(err, results) { 
       if (err) reject(err); 
       resolve(results); 
      }); 
     }); 
    }; 
    return new Promise(callbackFunction.bind(this), function (err) { 
     reject(err); 
    }); 
} 
+0

何内部getCollectionについて()?私もそのトリック( 'var self = this')をする必要がありますか? – 3irhui34t34

+0

はい、 'getCollection'に' Mongo'クラスのインスタンスを格納する必要があります。そうでないと、 'this.'で使用している変数の値が未定義になります。 –

0

次のようにあなたの挿入機能を更新 -

this.insert = function(docs) { 
    var _self = this; 
    return new Promise(function (resolve, reject) { 
     _self.getCollection().then(function(collection) { 
      collection.insert(docs, function(err, results) { 
       if (err) reject(err); 
       resolve(results); 
      }); 
     }); 
    }, function (err) { 
     reject(err); 
    }); 
} 

thisMongoクラスを参照していないどこにコールバック関数内getCollectionを呼び出しているため、このエラーを取得しています。したがって、変数にMongoクラス参照を格納して、それを使用する必要があります。あなたがgetCollection機能を呼び出している

関連する問題