这里的用例是我正在使用mysql,我想允许编写一个函数: - 开始交易 - 执行一些sql语句 - 提交交易 如果在任何时候出错: - 回滚交易
这可以很好地使用async.waterfall,代码如下:
async.waterfall([
// start transaction (i.e. "begin;")
function(callback) {
conn.beginTransaction(function(err) {
callback(err);
})
},
// step 1: create temp table which will contain our changed values
function(callback) {
conn.query(createTempTableQuery, null, function(err, result) {
callback(err);
});
},
// step 2: insert the changed values into our temp table
function(callback) {
conn.query(populateTempTableQuery, [populateTempTableColumns, populateTempTableValues], function(err, result) {
callback(err);
});
},
// step 3: run some sql update statement
function(callback) {
conn.query(updateSqlQuery, updateSqlValues, function(err, result) {
callback(err);
});
},
// finally, commit our changes
function(callback) {
conn.commit(function(err) {
callback(err);
});
}
], function(err) {
// if we hit an error at any step we need to rollback the transaction:
if (err) {
conn.rollback(function() {
logger.warn("Rolling back changes");
res.status(400).json({ message: "Unable to edit, Error: " + err });
});
}
else {
res.status(200).json({ message: "Successfully made edits." });
}
});

这很好用,但我想知道是否有办法不必编写每个函数,如:
conn.query(populateTempTableQuery, [populateTempTableColumns, populateTempTableValues], function(err, result) {
callback(err);
});

每一次。理想情况下,我想要一些包装函数,我可以给出一组sql语句,然后async在begin / commit命令之间逐个运行它们。
基本上,是否可以写出如下内容:
function sqltransaction(sqlStatements, callback) {
// statements is an array of sql queries and values e.g.
// [{ query: "SELECT id FROM users WHERE name = ?", values: ["Peter"] },{ query: "SELECT accessLevel FROM permissions WHERE name = ?", values: ["Paul"] },{ query: "UPDATE users SET status = ? WHERE name = ?", values: ["DISABLED","David"] }]
// async accepts an array of functions, so we can do something like
var functionsArray = [async.constant(sqlStatements), beginTransaction];
for (var i = 0; i < sqlStatements.length; i++) {
var args = ["conn","i","sqlStatements","results","callback"];
var code = "conn.query(sqlStatements[i].query, sqlStatements[i].values, function(err, result) {results[i]=result;callback(err,sqlStatements,results);});"
var sqlfunction = new Function(args, code);
functionsArray.push(sqlfunction(conn,i,sqlStatements,results,callback))
}
async.waterfall(functionsArray, function(err, result) {
// etc
})
&#13;
我所拥有的代码或多或少是上面的代码,但我遇到了没有定义回调的错误(我想async.waterfall回调只在瀑布已经启动时才被定义)。
我想要做的事情是不可能的,或者我认为这完全错了。这是什么?