Node js:Mongoose 中间件中的 Bluebird Promisify
Node js: Bluebird Promisify in Mongoose middleware
我有一个如下所示的用户模型:
var Promise = require("bluebird")
var mongoose = require("mongoose");
var mongooseAlias = require('mongoose-aliasfield');
var bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'));
var Schema = mongoose.Schema;
var userSchema = new Schema({
u: { type: String, required: true, trim: true, index: { unique: true }, 'alias': 'userId' },
fb: { type: String, required: true, 'alias': 'fbAccessToken' },
ap: { type: String, required: true, 'alias': 'apiAccessToken' },
f: { type: String, required: true, 'alias': 'firstName' },
l: { type: String, required: true, 'alias': 'lastName' },
e: { type: String, required: true, 'alias': 'email' }
});
// Execute before each user.save() call
userSchema.pre('save', function(callback) {
var user = this;
// return if token hasn't changed
if (!user.isModified('fb') && !user.isModified('ap'))
return callback();
// token changed so we need to hash it
bcrypt.genSalt(5, function(err, salt) {
if (err) return callback(err);
bcrypt.hash(user.fb, salt, null, function(err, hash) {
if (err) return callback(err);
user.fb = hash;
bcrypt.genSalt(5, function(err, salt) {
if (err) return callback(err);
bcrypt.hash(user.ap, salt, null, function(err, hash) {
if (err) return callback(err);
user.ap = hash;
callback();
});
});
});
});
});
userSchema.plugin(mongooseAlias);
module.exports = mongoose.model('User', userSchema);
我现在正在尝试学习 Bluebird,所以我像这样清理了 bcrypt 代码:
userSchema.pre('save', function(callback) {
var user = this;
// return if token hasn't changed
if (!user.isModified('fb') && !user.isModified('ap'))
return callback();
var p1 = bcrypt.genSaltAsync(5).then(function (salt) {
return bcrypt.hash(user.fb, salt, null);
}).then(function (hash) {
user.fb = hash;
});
var p2 = bcrypt.genSaltAsync(5).then(function (salt) {
return bcrypt.hash(user.ap, salt, null);
}).then(function (hash) {
user.ap = hash;
});
Promise.all(p1, p2).then(function () {
callback();
}).catch(function (err) {
callback(err);
});
});
我可以"promisify"再进一步吗?或者更确切地说,我是否在这里遗漏了一些可以使它更优雅的东西?我是否需要以某种方式承诺 userSchema.pre 调用?
干杯
我认为你的解决方案是正确的。我更喜欢做一些不同的事情(但我并不是说这样更好):
bcrypt.genSaltAsync(5)
.then(function (salt) {
return bcrypt.hash(user.fb, salt, null);
})
.then(function (hash) {
user.fb = hash;
})
.then(function (){
return bcrypt.genSaltAsync(5);
})
.then(function (salt) {
return bcrypt.hash(user.ap, salt, null);
})
.then(function (hash) {
user.ap = hash;
})
.then(function () {
callback();
})
.catch(function (err) {
callback(err);
});
我喜欢我的解决方案,因为一切都在一个流程中,乍一看你知道发生了什么。在我的解决方案中,第二个盐函数在第一个之后解析。在您的解决方案中,每个解决方案都在并行解决(我不检查每个解决方案的性能)
我有一个如下所示的用户模型:
var Promise = require("bluebird")
var mongoose = require("mongoose");
var mongooseAlias = require('mongoose-aliasfield');
var bcrypt = Promise.promisifyAll(require('bcrypt-nodejs'));
var Schema = mongoose.Schema;
var userSchema = new Schema({
u: { type: String, required: true, trim: true, index: { unique: true }, 'alias': 'userId' },
fb: { type: String, required: true, 'alias': 'fbAccessToken' },
ap: { type: String, required: true, 'alias': 'apiAccessToken' },
f: { type: String, required: true, 'alias': 'firstName' },
l: { type: String, required: true, 'alias': 'lastName' },
e: { type: String, required: true, 'alias': 'email' }
});
// Execute before each user.save() call
userSchema.pre('save', function(callback) {
var user = this;
// return if token hasn't changed
if (!user.isModified('fb') && !user.isModified('ap'))
return callback();
// token changed so we need to hash it
bcrypt.genSalt(5, function(err, salt) {
if (err) return callback(err);
bcrypt.hash(user.fb, salt, null, function(err, hash) {
if (err) return callback(err);
user.fb = hash;
bcrypt.genSalt(5, function(err, salt) {
if (err) return callback(err);
bcrypt.hash(user.ap, salt, null, function(err, hash) {
if (err) return callback(err);
user.ap = hash;
callback();
});
});
});
});
});
userSchema.plugin(mongooseAlias);
module.exports = mongoose.model('User', userSchema);
我现在正在尝试学习 Bluebird,所以我像这样清理了 bcrypt 代码:
userSchema.pre('save', function(callback) {
var user = this;
// return if token hasn't changed
if (!user.isModified('fb') && !user.isModified('ap'))
return callback();
var p1 = bcrypt.genSaltAsync(5).then(function (salt) {
return bcrypt.hash(user.fb, salt, null);
}).then(function (hash) {
user.fb = hash;
});
var p2 = bcrypt.genSaltAsync(5).then(function (salt) {
return bcrypt.hash(user.ap, salt, null);
}).then(function (hash) {
user.ap = hash;
});
Promise.all(p1, p2).then(function () {
callback();
}).catch(function (err) {
callback(err);
});
});
我可以"promisify"再进一步吗?或者更确切地说,我是否在这里遗漏了一些可以使它更优雅的东西?我是否需要以某种方式承诺 userSchema.pre 调用?
干杯
我认为你的解决方案是正确的。我更喜欢做一些不同的事情(但我并不是说这样更好):
bcrypt.genSaltAsync(5)
.then(function (salt) {
return bcrypt.hash(user.fb, salt, null);
})
.then(function (hash) {
user.fb = hash;
})
.then(function (){
return bcrypt.genSaltAsync(5);
})
.then(function (salt) {
return bcrypt.hash(user.ap, salt, null);
})
.then(function (hash) {
user.ap = hash;
})
.then(function () {
callback();
})
.catch(function (err) {
callback(err);
});
我喜欢我的解决方案,因为一切都在一个流程中,乍一看你知道发生了什么。在我的解决方案中,第二个盐函数在第一个之后解析。在您的解决方案中,每个解决方案都在并行解决(我不检查每个解决方案的性能)