首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >让Knex.js事务使用ES7异步/等待

让Knex.js事务使用ES7异步/等待
EN

Stack Overflow用户
提问于 2016-11-14 01:22:06
回答 6查看 22.3K关注 0票数 22

我正在尝试将ES7的异步/等待与knex.js事务。结合起来。

虽然我可以轻松地处理非事务性代码,但我很难使用前面提到的异步/等待结构使事务正常工作。

我用的是此模块用于模拟异步/等待

以下是我目前的情况:

非事务性版本:

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

app.js

代码语言:javascript
复制
// 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

代码语言:javascript
复制
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

代码语言:javascript
复制
// 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]

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-11-14 01:56:14

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

下面是关于如何将任意函数转换为使用承诺的说明,以便它们可以使用异步/等待:

试图了解如何使用BlueBird进行编程

从本质上说,你想这样做:

代码语言:javascript
复制
var transaction = knex.transaction;
knex.transaction = function(callback){ return knex.transaction(callback); }

这是因为“异步/等待需要一个带有单个回调参数的函数,或者一个允诺”,而knex.transaction则如下所示:

代码语言:javascript
复制
function transaction(container, config) {
  return client.transaction(container, config);
}

或者,您可以创建一个新的async函数并像这样使用它:

代码语言:javascript
复制
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,例如上面的那些)。

票数 12
EN

Stack Overflow用户

发布于 2016-11-28 19:29:32

我在任何地方都找不到可靠的答案(使用回滚和提交),所以这里是我的解决方案。

首先,您需要"Promisify“knex.transaction函数。这里有一些库,但举一个简单的例子,我这样做了:

代码语言:javascript
复制
const promisify = (fn) => new Promise((resolve, reject) => fn(resolve));

此示例创建一个博客文章和一个注释,如果两者都有错误,则将两者都回滚。

代码语言:javascript
复制
const trx = await promisify(db.transaction);

try {
  const postId = await trx('blog_posts')
  .insert({ title, body })
  .returning('id'); // returns an array of ids

  const commentId = await trx('comments')
  .insert({ post_id: postId[0], message })
  .returning('id'); 

  await trx.commit();
} catch (e) {
  await trx.rollback();
}
票数 32
EN

Stack Overflow用户

发布于 2020-07-23 12:07:25

下面是一种以异步/等待方式编写事务的方法。

-- MySQL.工作得很好

代码语言:javascript
复制
const trx = await db.transaction();
try {
    const catIds = await trx('catalogues').insert({name: 'Old Books'});
    const bookIds = await trx('books').insert({catId: catIds[0], title: 'Canterbury Tales' });
    await trx.commit();
} catch (error) {
    await trx.rollback(error);
}
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40580674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档