获取使用ES7 async / await的Knex.js事务 [英] Get Knex.js transactions working with ES7 async/await
问题描述
我正在尝试将ES7的async / await与 knex.js交易相结合。
I'm trying to couple ES7's async/await with knex.js transactions.
虽然我可以轻松使用非事务性代码,但我很难使用前面提到的异步/等待结构来使事务正常工作。
Although I can easily play around with non-transactional code, I'm struggling to get transactions working properly using the aforementioned async/await structure.
我正在使用此模块来模拟异步/等待
以下是我目前所拥有的:
Here's what I currently have:
工作正常,但不是交易
// assume `db` is a knex instance
app.post("/user", async((req, res) => {
const data = {
idUser: 1,
name: "FooBar"
}
try {
const result = await(user.insert(db, data));
res.json(result);
} catch (err) {
res.status(500).json(err);
}
}));
user.js
user.js
insert: async (function(db, data) {
// there's no need for this extra call but I'm including it
// to see example of deeper call stacks if this is answered
const idUser = await(this.insertData(db, data));
return {
idUser: idUser
}
}),
insertData: async(function(db, data) {
// if any of the following 2 fails I should be rolling back
const id = await(this.setId(db, idCustomer, data));
const idCustomer = await(this.setData(db, id, data));
return {
idCustomer: idCustomer
}
}),
// DB Functions (wrapped in Promises)
setId: function(db, data) {
return new Promise(function (resolve, reject) {
db.insert(data)
.into("ids")
.then((result) => resolve(result)
.catch((err) => reject(err));
});
},
setData: function(db, id, data) {
data.id = id;
return new Promise(function (resolve, reject) {
db.insert(data)
.into("customers")
.then((result) => resolve(result)
.catch((err) => reject(err));
});
}
尝试使其成为交易
user.js
Attempt to make it transactional
user.js
// Start transaction from this call
insert: async (function(db, data) {
const trx = await(knex.transaction());
const idCustomer = await(user.insertData(trx, data));
return {
idCustomer: idCustomer
}
}),
似乎 await(knex.transaction())
返回此错误:
[TypeError:容器不是函数]
推荐答案
Async / await基于promises,所以看起来你只需要包装所有knex方法来返回promise兼容的对象。
Async/await is based around promises, so it looks like you'd just need to wrap all the knex methods to return "promise compatible" objects.
这里是关于如何将任意函数转换为使用promises的描述,因此它们可以使用async / await:
Here is a description on how you can convert arbitrary functions to work with promises, so they can work with async/await:
试图了解promisification如何与BlueBird合作
基本上你想这样做:
var transaction = knex.transaction;
knex.transaction = function(callback){ return knex.transaction(callback); }
这是因为async / await要求具有单个回调参数的函数,或者承诺,而 knex.transaction
如下所示:
This is because "async/await requires the either a function with a single callback argument, or a promise", whereas knex.transaction
looks like this:
function transaction(container, config) {
return client.transaction(container, config);
}
或者,你可以创建一个新的 async
函数并像这样使用它:
Alternatively, you can create a new async
function and use it like this:
async function transaction() {
return new Promise(function(resolve, reject){
knex.transaction(function(error, result){
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
// Start transaction from this call
insert: async (function(db, data) {
const trx = await(transaction());
const idCustomer = await(person.insertData(trx, authUser, data));
return {
idCustomer: idCustomer
}
})
这也可能有用: Knex交易与承诺
(另请注意,我不熟悉knex的API,所以不确定传递给 knex.transaction
的参数是什么,以上只是例如。)
(Also note, I'm not familiar with knex's API, so not sure what the params are passed to knex.transaction
, the above ones are just for example).
这篇关于获取使用ES7 async / await的Knex.js事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!