使用其他模块中的函数,避免异步回调地狱
Avoiding callback hell with async, using functions from other modules
我有一个用户模块,我在其中定义要在代码中使用的函数。当我创建密码时,我想使用以下功能:
用户模块:
//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() {
}
]);
}
});
我看了不少例子,但似乎找不到有人在异步中调用外部模块代码的地方。
感谢@Bergi的反馈,我将研究承诺。不管是否有人想这样做,这里是我的解决方案。我强烈建议查看异步瀑布文档——这是我发现的一些更好的材料。
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)
}
});
})
相关文章:
- Meteor:异步回调问题
- JavaScript中的异步回调
- 如何将此异步回调转换为生成器
- 在Nodejs中堆叠异步回调事件的最佳方式
- 从异步回调中获取值
- jasmine 2-在jasmine指定的超时时间内未调用异步回调.DEFAULT_TIMEOUT_INTERVAL
- 将数据注入异步回调(使用 node.js)
- 由于异步回调,变量被覆盖
- 管理Meteor中的异步回调
- 如何等到异步回调完成后才能使用检索到的数据
- Node.JS函数返回异步回调函数的值
- 将Node REPL调整为不阻塞异步回调的提示
- 如何正确地将异步回调与react中的表单操作连接起来
- 返回异步回调作为最佳实践
- 使用其他模块中的函数,避免异步回调地狱
- Node.js:异步回调混淆
- JavaScript中的调试技术.异步回调
- Javascript OOP-在异步回调中丢失了这一点
- 在 JavaScript 中的异步回调函数中访问“this”
- 异步回调后返回