使用 ES7 async/await 获取 Knex.js 事务 [英] Get Knex.js transactions working with ES7 async/await

查看:67
本文介绍了使用 ES7 async/await 获取 Knex.js 事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将 ES7 的 async/await 与 knex.js 事务结合起来.

I'm trying to couple ES7's async/await with knex.js transactions.

虽然我可以轻松地使用非事务性代码,但我很难使用上述 async/await 结构使事务正常工作.

Although I can easily play around with non-transactional code, I'm struggling to get transactions working properly using the aforementioned async/await structure.

我正在使用这个模块来模拟异步/等待

这是我目前拥有的:

工作正常但不是事务性的

// 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

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

// 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: container is not a function]

推荐答案

Async/await 基于 promises,所以看起来你只需要包装所有 knex 方法来返回promise compatible"对象.

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.

这里描述了如何将任意函数转换为与 Promise 一起使用,以便它们可以与 async/await 一起使用:

Here is a description on how you can convert arbitrary functions to work with promises, so they can work with async/await:

尝试了解如何使用 BlueBird 进行承诺

基本上你想这样做:

var transaction = knex.transaction;
knex.transaction = function(callback){ return knex.transaction(callback); }

这是因为async/await 需要一个带有单个回调参数的函数,或者一个 promise",而 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 Transaction with Promises

(另外请注意,我对 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆