我正在尝试将ES7的异步/等待与knex.js transactions.结合在一起

尽管我可以轻松地处理非事务处理代码,但是我仍在努力使用上述异步/等待结构来使事务正常工作。

我正在使用this module to simulate async/await

这是我目前拥有的:

非交易版本:

工作正常,但不是事务性的

app.js

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

最佳答案

异步/等待基于promise,因此看起来您只需要包装所有的knex方法即可返回“ promise 兼容”对象。

这是有关如何将任意函数转换为可与Promise一起使用,以便它们可与async/await一起使用的说明:

Trying to understand how promisification works with BlueBird

本质上,您想这样做:

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

这是因为“异步/等待需要一个带有单个回调参数的函数或一个Promise”,而knex.transaction看起来像这样:
function transaction(container, config) {
  return client.transaction(container, config);
}

另外,您可以创建一个新的async函数并按以下方式使用它:
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,以上只是示例)。

关于javascript - 获取使用ES7异步/等待的Knex.js事务,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40580674/

10-13 02:47