2016-03-29 8 views
1

У меня есть пользовательский модуль, где я определяю функции, которые будут использоваться через код. Когда я создаю пароль, который я хотел бы использовать эти функции:Избегайте обратного вызова ада с помощью функций из других модулей

Модуль пользователя:

//insert a local user into the database 
User.prototype.insertLocalUser = function (email, password, cb) { 

    var sql = "INSERT INTO VCUSER (VCUSER_EMAIL, VCUSER_PASSWORD) values ('" + email 
    + "','" + password + "')"; 

    db.get().query(sql, function (err, rows) { 
    if (err) return cb(err); 

    return cb(err, rows); 
    }); 
}; 

//generate hash function for password 
User.prototype.generateHash = function (password, cb) { 

    bcrypt.genSalt(10, function(err, salt) { 
    if (err) return cb(err); 

    bcrypt.hash(password, salt, null, function(err, hash) { 
     return cb(err, hash); 
    }); 
    }); 
}; 

Passport.js:

Вот где я делаю так, получил это не слишком плохо, но я в настоящее время застрял в попытке понять, как исправить простую вложенную проблему обратного вызова с помощью async, и я не хочу двигаться вперед с гораздо более сложным гнездом обратного вызова.

//minor callback hell 
     user.findByEmail(email, function (err, rows) { 
     if (err) return done(err); 

     if (rows.length) { //user must already exist prompt user 
      return done(null, false, req.flash('signupMessage', 'That email is already taken.')); 
     } else { 

      user.generateHash(password, function (err, hash) { 
      if (err) return done(err); 

      //insert a user with the newly hashed password into the database 
      user.insertLocalUser(email, hash, function (err, rows) { 
       if (err) return done(err); 

       user.VCUSER_USERID = rows.insertId; 

       //return the user we are done, they should be serialized and redirected 
       return done(null, user); 
      }); 
      }); 
     } 
     }); 

Я пытаюсь сделать что-то вроде этого:

//first search to see if the user already exists 
    user.findByEmail(email, function (err, rows) { 
    if (err) return done(err); 

    if (rows.length) { //user must already exist prompt user 
     return done(null, false, req.flash('signupMessage', 'That email is already taken.')); 
    } else { 
     async.series([ 
     //code avoid callback hell here 
     user.generateHash... { 

     } 

     user.insertLocalUser() { 

     } 
     ]); 
    } 
    }); 

Я смотрел довольно много примеров, но я не могу показаться, чтобы найти что-то, где кто-то звонит Посторонний модули кода внутри асинхронном.

+1

Пообещано. Просто используйте обещания. – Bergi

+1

Я второй совет по звуку от @Bergi, и я рекомендую избегать SQL-инъекции путем параметризации вашего запроса (например, использовать подготовленный оператор). –

+1

Я танцую вокруг обещаний, @ Берги, я попытаюсь это сделать. Я все еще не могу найти хороших примеров использования обещания при вызове других функций модулей. – Weston

ответ

1

Я буду смотреть в обещания благодаря обратной связи @ Bergi. Независимо от того, кто хочет сделать это, я решил это. Я настоятельно рекомендую рассмотреть async waterfall documentation, это был лучший материал, который я нашел.

async.waterfall([ 
    //look in database for existing users with email inputed return as results 
    function findUser(cb) { 
     var sql = "SELECT * FROM VCUSER WHERE VCUSER_EMAIL = '" + email + "'"; 

     db.get().query(sql, function (err, result) { 
     if (err) { cb(err); } 

     cb(null, result); 
     }); 
    }, 
    //check if there were any results, if so prompt, if not continue with user creation 
    function generateHash(result, cb) { 
     if (result.length) { return done(null); } //TODO determine how this is handled back to UI 

     bcrypt.genSalt(10, function(err, salt) { 
     if (err) { cb(err); } 

     bcrypt.hash(password, salt, null, function(err, hash) { 
      cb(null, hash); 
     }); 
     }); 
    }, 
    //using recently generated hash create a user 
    function insertNewUser(hash, cb) { 
     var sql = "INSERT INTO VCUSER (VCUSER_FIRSTNAME, VCUSER_LASTNAME, VCUSER_EMAIL, VCUSER_PASSWORD) " + 
     "values ('" + req.body.firstName + "','" + req.body.lastName + "','" + email + "','" + hash + "')"; 

     db.get().query(sql, function (err, rows) { 
     if (err) { cb(err); } 

     cb(null, rows); 
     }); 
    } 
    ], function (err, rows) { 
    if (err) { return done(err); } 
    else { 
     user.VCUSER_USERID = rows.insertId; 
     return done(null, user) 
    } 
    }); 
}) 
Смежные вопросы