猫鼬预保存是否使用了不正确的"this"上下文?



有人能找出我下面的代码出了什么问题吗?

从文档来看,Mongoose .pre('save')方法中的this应该是模型本身,但在我下面的代码中,this最终是一个空对象。

const Mongoose = require('./lib/database').Mongoose;
const Bcrypt = require('bcrypt');
const userSchema = new Mongoose.Schema({
    email: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true }
});
userSchema.pre('save', (next) => {
    const user = this;
    Bcrypt.genSalt((err, salt) => {
        if (err) {
            return next(err);
        }
        Bcrypt.hash(user.password, salt, (err, encrypted) => {
            if (err) {
                return next(err);
            }
            user.password = encrypted;
            next();
        });
    });
});
const User = Mongoose.model('User', userSchema);

保存用户时,我会得到以下错误[Error: data and salt arguments required]

function createUser(email, password, next) {
    const user = new User({
        email: email,
        password: password
    });
    user.save((err) => {
        if (err) {
            return next(err);
        }
        return next(null, user);
    });
}
createUser('test@email.com', 'testpassword', (err, user) => {
    if (err) {
        console.log(err);
    }
    else {
        console.log(user);
    }
    process.exit();
});

如果我删除.pre('save'),那么它当然可以保存。我使用的Mongoose版本是4.2.6。

这里的问题是一个胖箭头函数。您必须用简单的函数重写回调。这里的小例子显示差异

var obj = {};
obj.func1 = function () {
    console.log(this === obj);
};
obj.func2 = () => {
    console.log(this === obj);
};
obj.func1(); // true
obj.func1.bind(obj)(); // true
obj.func2(); // false
obj.func2.bind(obj)(); // false

我能够解决这个问题。事实证明,ES6中的Arrow函数保留了声明范围的上下文,而不是使用调用范围的上下文。因此,将代码更改为下面的代码解决了这个问题。

userSchema.pre('save', function (next) {
    Bcrypt.genSalt((err, salt) => {
        if (err) {
            return next(err);
        }
        Bcrypt.hash(this.password, salt, (err, encrypted) => {
            if (err) {
                return next(err);
            }
            this.password = encrypted;
            next();
        });
    });
});

感谢Michelem告诉我ES6可能是罪魁祸首。

我认为应该是:

userSchema.pre('save', (next) => {
    var user = this;
    // Try this
    // console.log(user);
    Bcrypt.genSalt(function (err, salt) {
        if (err) {
            return next(err);
        }
        Bcrypt.hash(user.password, salt, null, function (err, encrypted) {
            if (err) {
                return next(err);
            }
            user.password = encrypted;
            next();
        });
    });
});

但请检查用户是正确的对象。

相关内容

  • 没有找到相关文章

最新更新