如何使用MongoDB中的值更新Javascript类的成员变量?

如何使用MongoDB中的值更新Javascript类的成员变量?,javascript,mongodb,callback,asynccallback,Javascript,Mongodb,Callback,Asynccallback,我有一个作业类,用Javascript定义如下: var Job = function() {}; module.exports = Job; 然后,我使用其原型定义一个成员函数。这很好,直到我尝试使用数据库中的值来设置成员变量: // Create from an existing job ID Job.prototype.createFromID = function( inID, callback ) { // Start by making sure we're invali

我有一个作业类,用Javascript定义如下:

var Job = function() {};
module.exports = Job;
然后,我使用其原型定义一个成员函数。这很好,直到我尝试使用数据库中的值来设置成员变量:

// Create from an existing job ID
Job.prototype.createFromID = function( inID, callback ) {

    // Start by making sure we're invalid 
    this.id = "";

    // Connect to database
    var db = MongoClient.connect('mongodb://localhost:27017/nodepurple', function( err, db ) {
        if (err) { return false; }

        // Find the job document we're interested in
        db.collection('jobs').find({ jobID: inID }).limit( 1 ).toArray( function( err, theJobs ) {
            if (theJobs.length == 1) {
                this.id = theJobs[0].jobID;

                // Close the database
                db.close();

                callback( (this.id != ""), this );
            }
        }); // Find
    }); // Connect
}
此功能的目的是:

  • 获取定义我感兴趣的特定作业的MongoDB文档(由“inID”参数定义)
  • 填充为其调用此函数的作业实例的一组成员变量
这不起作用。我想我理解为什么它不起作用,当这些MongoDB回调返回时,我假设我不再处于正确的环境中来实现这一点,但我正在努力了解如何解决这一问题


那么,我如何获取MongoDB为jobID返回的值,并使用该值填充我正在处理的特定作业实例中的“id”成员变量呢?

是的,你说得对,在回调
中,此
不再引用
作业
对象。要修复此问题,你有两个选项

1) 保留对作业对象的引用,以便在回调中使用该对象来设置
id

Job.prototype.createFromID = function( inID, callback ) {

    this.id = "";
    var self = this;

    var db = MongoClient.connect('mongodb://localhost:27017/nodepurple', function( err, db ) {
        if (err) { 
            return false; 
        }
        db.collection('jobs').find({ jobID: inID }).limit( 1 ).toArray( function( err, theJobs ) {
            if (theJobs.length == 1) {
                self.id = theJobs[0].jobID;
                db.close();
                callback( (self.id != ""), self );
            }
        }); 
    }); 
}
2) 将作业对象绑定到回调函数

Job.prototype.createFromID = function( inID, callback ) {

    this.id = "";
    var mongoCallback2 = function(err, theJobs) {
        if (theJobs.length == 1) {
            this.id = theJobs[0].jobID;
            db.close();
            callback((this.id != ""), this);
        }
    }
    var mongoCallback1 = function(err, db) {
        if (err) { return false; }
        db.collection('jobs').find({jobID: inID}).limit(1).toArray(mongoCallback2.bind(this)); 
    }); 

    var db = MongoClient.connect('mongodb://localhost:27017/nodepurple', mongoCallback1.bind(this));
}
3) 使用箭头函数。箭头函数不会更改上下文

Job.prototype.createFromID = function( inID, callback ) {

    this.id = "";

    var db = MongoClient.connect('mongodb://localhost:27017/nodepurple', (err, db) => {
        if (err) { 
            return false; 
        }
        db.collection('jobs').find({jobID: inID}).limit( 1 ).toArray((err, theJobs) => {
            if (theJobs.length == 1) {
                self.id = theJobs[0].jobID;
                db.close();
                callback((this.id != ""), this);
            }
        }); 
    }); 
}

并非所有浏览器或所有浏览器版本都支持箭头功能,但有一些工具可以将您的代码转换为适用于更广泛的浏览器和浏览器版本。

非常感谢!我已经想到了方法1,只是测试了它,当然它是有效的。它看起来也很糟糕,与我多年来建立起来的OOP意识格格不入。但这也许是Javascript的预期结果;我开始认为尝试在Javascript中使用类可能弊大于利。您的第二种方法很有趣,但我永远不会编写这样的代码;感觉完全颠倒了。@Davidvandriesche我在答案中添加了一个新选项。我对JavaScript OOP也有同样的问题,但是新的语法(箭头函数和
超级
关键字)使事情变得更简单。啊,非常酷。我在node.js的一个node red项目中使用了它,所以我假设在让它工作时不会有太多问题。我现在使用的是你的第一种方法,效果很好,但我将尝试第二种方法,并阅读这个类和超级材料(以及箭头);感觉更像是这样。谢谢你,提图斯@davidvandries是的,您可以在节点应用程序中使用新语法而不会出现问题。我很高兴能帮上忙。祝你好运。嗨,提图斯,这个很好用。我读了很多关于更高级Javascript的文章,你的方法3工作得非常好。语法仍然有点笨拙,但不必使用这个伪“self”变量非常好,我发现这种语法实际上比常规函数回调更容易理解。再次感谢!