Mongoose instance method to modify 'this' document throws TypeError: Cannot set property '...' of undefined

Mongoose instance method to modify 'this' document throws TypeError: Cannot set property '...' of undefined

我尝试创建一个 mongoose instance method 来创建一个密码重置令牌,我可以通过电子邮件将其发送给用户。

我的功能基于 dudify method from a scotch.io tutorial called Easily Develop Node.js and MongoDB Apps with Mongoose


models.js

var userSchema = new mongoose.Schema({
    ...
    auth: {
        password: String,
        passToken: String,
        tokenExpires: Date
    },
    ...
});

userSchema.methods.createToken = function(next){
    require('crypto').randomBytes(16, function(err,buf){
        if (err){ next(err); }
        else {
            this.auth.passToken = buf.toString('hex');
            this.auth.tokenExpires = Date.now() + 3600000;
            this.save();
        }
    });
};

错误

/path/to/project/config/models.js:85
    this.auth.passToken = buf.toString('hex');
                        ^

TypeError: Cannot set property 'passToken' of undefined
    at InternalFieldObject.ondone (/path/to/project/config/models.js:85:25)

问题是 this 不再引用模型实例:它引用了 crypto.randomBytes()

我的解决方案是将 this 设置为函数外的变量 (user):

userSchema.methods.createToken = function(next){
    var user = this;
    require('crypto').randomBytes(16, function(err,buf){
       if (err){ next(err); }
        else {
            user.auth.passToken = buf.toString('hex');
            user.auth.tokenExpires = Date.now() + 3600000;
            user.save();
        }
    });
};

回想起来,这对我来说是非常愚蠢的,但它发生在我们最好的人身上。希望这会节省其他人的时间。