我是后端 Node.Js 和 JavaScript 网络开发的新手。我看到回调中的回调可能会很痛苦,并且有一些模块可以避免这种情况。这些模块之一是异步的,https://github.com/caolan/async
我已阅读文档,但很难开始和理解如何去做。
例如,我有这个函数“check_aut_user”,如何使用异步转换此代码?
function check_auth_user(username, password, done) {
var client = new pg.Client("pg://user:pass@127.0.0.1/database");
client.connect(function(err) {
// If not get the connection
if(err) { return console.error('could not connect to postgres', err); }
// Query the user table
client.query('select * from "user" where username = $1 and password = $2', [username, password], function(err, result) {
if(err) { return console.error('error running query', err); }
if (result.rowCount > 0) {
var res = result.rows[0];
console.log(res);
passport.serializeUser(function(res, done) {
//console.log("serializer: " + res);
done(null, res);
});
passport.deserializeUser(function(user, done) {
//console.log("deserializer: " + user['password']);
done(null, res);
});
return done(null, res);
} else {
return done(null, false);
}
});
});
}
最好的问候,
最佳答案
在我看来,回调 hell 实际上是两个问题的混合体:
- 匿名内联函数。
- 缩进。
少量使用任何一种都可以,但它们一起会使代码变得僵硬且难以维护。避免回调 hell 的解决方案是通过以下方式避免这两件事:
- 命名您的函数并将它们从函数调用中提取出来。
- 早点返回以避免故意。
按照这些原则,您的代码可以重写为:
function check_auth_user(username, password, done) {
// Make a new client and open the connection.
function connect(callback) {
var client = new pg.Client("pg://user:pass@127.0.0.1/database");
client.connect(function (err) {
if (err) {
console.error('could not connect to postgres', err);
return callback(err);
}
callback(null, client);
});
}
// Query the database.
function query(callback, results) {
var client = results.client;
var q = 'select * from "user" where username = $1 and password = $2';
var params = [username, password];
client.query(q, params, function (err, result) {
if (err) {
console.error('error running query', err.stack || err.message);
return callback(err);
}
callback(null, result);
});
}
// Do stuff with the result of the query.
function handleQueryResult(callback, results) {
var result = results.query;
if (result.rowCount === 0) {
return callback();
}
var row = result.rows[0];
console.log(row);
passport.serializeUser(function(res, done) {
done(null, res);
});
passport.deserializeUser(function(user, done) {
done(null, res);
});
callback(null, row);
}
// Let async handle the order. Allows remixing.
async.auto({
connect: [connect],
query: ['connect', query],
row: ['query', handleQueryResult]
}, function (err, results) {
if (err) {
return done(err);
}
// Callback with the row.
done(null, results.row);
});
}
我用过 async.auto
在这里,即使 async.waterfall
也行。其背后的原因是很难在 waterfall
中移动、添加或删除步骤,而这一直是错误的来源。 auto
让您无需担心添加步骤,顺序/并行性由异步处理。
这显然使用了更多的垂直空间,但我认为这是为模块化付出的很小的代价。
关于Node.js/Async - 如何避免异步回调 hell ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20961919/