Bookshelf js模型导致save/changed循环

Bookshelf js model causes save/changed loop

以下 Bookshelf 模型在保存模型时对用户密码进行哈希处理,唯一的问题是,如果我将 model.set() 调用更改为 model.save(),它将进入无限 save/changed循环。

var User = bookshelf.Model.extend({
    tableName: 'users',
    hasTimestamps: true,

    constructor: function() {
        var self = this;
        bookshelf.Model.apply(this, arguments);

        this.on('saving', function(model) {
            if(!model.get('password')) {
                return self.hashPassword(model);
            }
        });
    },

    hashPassword: function(model) {
        bcrypt.genSalt(10, function(error, salt) {
            bcrypt.hash(model.attributes.password, salt, function(error, hash) {
                model.set({password: hash});
                console.log(model.attributes);
            });
        });
    }
});

我知道 Backbone 有一个 silent: true 选项,你可以通过它,这样 save() 就不会触发更改事件,但我认为 Bookshelf 不支持它。

如何在不引起 save/changed 循环的情况下保存 model.set() 所做的更改?

所以事实证明模型在 hash_password 方法返回值之前正在保存,所以我像这样承诺 bcrypt 代码:

hashPassword: function(password) {
    return new Promise(function(resolve, reject) {
        bcrypt.genSalt(10, function(error, salt) {
            if(error) return reject(error);

            bcrypt.hash(password, salt, function(error, hash) {
                if(error) return reject(error);
                return resolve(hash);
            });
        });
    });
}

并完全重构模型的构造函数以使用它:

constructor: function() {
    var self = this;
    bookshelf.Model.apply(this, arguments);

    this.on('saving', function(model) {
        if(!model.attributes.password) {
            delete model.attributes.password;
        } else {
            return self.hashPassword(model.attributes.password)
            .then(function(hash) {
                model.set({ password: hash });
            });
        }
    });
}

希望这对某人有所帮助:-)