JS - Knex,将函数传递给Transaction

时间:2018-04-14 16:28:12

标签: javascript promise knex.js

我创建了一个node.js应用程序,它使用knex库进行数据库操作。该数据库是Microsoft SQL Server。我创建了一个名为db.js的脚本,它返回knex对象,我有一个controller.js脚本,可以实现实际需要的数据库操作。我将所有操作都包含在翻译语句中,这让我想到了我的问题。我想做的是传递一个参数,告诉事务回滚或提交。但是,每当我尝试传递此函数时,它就会失败。有谁知道这个功能是否可以实现?我能够使用catch函数执行此功能。

我不认为它的数据库是特定的,所以任何人都可以下载knex,将数据库连接起来并使用下面的代码进行操作。

example.js

/**
 * @param {userID} Int 
 * @param {rollback} Boolean 
 */
const getUsers = (userID, rollback) => {
    // Using tran as a transaction object:
    return db('master').transaction((tran) => {
        db('master')
        .select()
        .from('users')
        .where({ 'user_id': userID })
        .transacting(tran)
        .then(tran.rollback) // Works
        // .then(transact(tran, rollback)) throws error 
        .catch((error) => {
            logError(error, tran); // Works 
        });
        // .catch(tran.rollback);
    });
};
const logError = (error, transaction) => {
    transaction.rollback; 
    console.log('transaction error: ',error);
    console.log('transaction log: ',transaction);
};
const transact = (transaction, rollback) => {
    try {
        if (rollback) return transaction.rollback; 
        else return transaction.commit;
    } catch (error) {
        console.log(error); 
    }
}; 
const user = await getUsers(1, true); // error is thrown
assert.strictEqual(user.constructor === Array, true);
assert.strictEqual(user.length == 0, true);

错误消息

Error: the array [   {
    "user_id": 1
    "user_name": "JonnyBoy"
    "zip": 1200
    "email": "jjboy@test.com"
  } ] was thrown, throw an Error :)

1 个答案:

答案 0 :(得分:1)

then将函数作为其第一个参数。如果Promise结算,则传递给then的函数将使用Promise解析为的值进行调用。事务对象上的rollback属性是一个函数,因此您可以编写:

someQuery().then(trans.rollback)
rollback结算时,将调用

someQuery。你也可以写:

someQuery.then(result => trans.rollback(result))

这些陈述是等效的。

尽管如此,最低限度地说,您需要进行两项更改。一,修复你如何调用transact。例如:

.then(() => transact(tran, rollback))

并更改transact调用rollback的方式:

const transact = (trx, rollback) => {
  const action = rollback ? trx.rollback : trx.commit
  return action()
}

还要记住,rollback本身会返回一个被拒绝的Promise,并带有一般错误。您可以将自定义错误传递给rollback,它会拒绝该错误。