2015-09-26 2 views
1

У меня есть модель пользователя, которая выглядит следующим образом:Node JS: Bluebird Promisify в Mongoose промежуточного

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); 
    }); 
}); 

Могу ли я «обещать» его дальше? Вернее, я что-то упустил, чтобы сделать его более элегантным? Нужно ли мне как-то обещать запрос userSchema.pre?

Cheers

ответ

0

Я считаю, что ваше решение правильное. Я предпочитаю, чтобы сделать это немного по-другому (но я не говорю, что это лучше):

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); 
}); 

Мне нравится мое решение, потому что все в одном потоке и на первый взгляд, вы знаете, что происходит. В моем решении вторая функция соли решает сначала. В вашем решении каждый из них разрешает параллельную (я не проверю производительность каждого решения)

Смежные вопросы