是否可以将async.waterfall或async.series与动态生成的函数一起使用?

时间:2017-03-09 21:03:21

标签: javascript node.js node-mysql async.js

这里的用例是我正在使用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;
&#13;
&#13;

我所拥有的代码或多或少是上面的代码,但我遇到了没有定义回调的错误(我想async.waterfall回调只在瀑布已经启动时才被定义)。

我想要做的事情是不可能的,或者我认为这完全错了。这是什么?

0 个答案:

没有答案