- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 Knex、交易和 Promise 方面遇到了困难,非常感谢 SO 专家的帮助:)
通过阅读类似的帖子和许多有关 Promises 的文章,我知道我距离解决方案并不遥远,但发现以下代码对于这样一个简单的任务来说确实过于复杂。
此类仅公开一个函数,该函数接收先前构建的查询,并且需要在首次调用“load_user_settings”函数(使用 PostgreSQL 9.5 作为数据库)后运行它。我实际上需要第二个查询的结果(或错误),因此简单地将 trx.commit 放在“then”中对我来说不起作用。
我的函数末尾的 process.nextTick 确实感觉像是一个巨大的 hack,添加它是为了避免将我的整个应用程序更改为 Promises,因为目前这是不可行的。如果没有这个,我经常会发现自己出现 Promise 警告(“未处理的拒绝错误”),并在代码稍后抛出异常时挂起代码。
此外,我不时会在日志中看到以下警告:警告: promise 被拒绝且无错误:[对象未定义]我猜这个警告在某种程度上与这个问题有关......
如果可以找到仅使用回调的解决方案,那就太好了,因为我们的整个应用程序当前都在使用回调。
const pg = require('pg');
const async = require('async');
class MyClass {
constructor(connectionInfo) {
this.connectionInfo = connectionInfo; // This is an object containing user, password, database, host and port.
this.pgKnex = require('knex')({
client : 'pg',
connection : this.connectionInfo,
pool : {
min : 1,
max : 25
}
});
}
query(username, sql, params, callback) {
let response;
let error;
this.pgKnex.transaction((trx) => {
return this.pgKnex.raw(`SELECT load_user_settings(?)`, [username]).transacting(trx)
.then(() => {
return this.pgKnex.raw(sql, params).transacting(trx);
})
.then((result) => {
response = result;
return trx.commit();
}).catch((err) => {
error = err;
console.error(err);
return trx.rollback();
});
}).catch((err) => {
error = err;
console.error(err);
}).then(() => {
process.nextTick(() => {
callback(error, response);
});
});
}
}
module.exports = MyClass;
根据 Bergi 的评论,我编写了这个版本,它避免了任何黑客行为并删除了我的所有 promise 警告:
query(username, sql, params, callback) {
this.pgKnex.transaction((trx) => {
this.pgKnex.raw(`SELECT set_config('ims.username', ?, false)`, [username]).transacting(trx).asCallback((err, result) => {
if(err) {
trx.rollback().asCallback(() => {
console.error(err);
callback(err);
});
return;
}
this.pgKnex.raw(sql, params).transacting(trx).asCallback((err, result) => {
if(err) {
trx.rollback().asCallback(() => {
console.error(err);
callback(err);
});
return;
}
trx.commit().asCallback((commitErr) => {
callback(commitErr, result);
});
});
});
}).asCallback((err, result) => {
// Nothing to do here ... I guess?
});
}
但我仍然觉得这可以改进......
最佳答案
让我尝试简化一下:
query(username, sql, params, callback) {
this.pgKnex.transaction((trx) => {
return this.pgKnex.raw(`SELECT set_config('ims.username', ?, false)`, [username])
.transacting(trx)
.then(() => {
return this.pgKnex.raw(sql, params)
.transacting(trx);
});
}).asCallback(callback);
}
当使用事务 block 时,您可以返回一个Promise
,如果Promise
被解析/拒绝,knex将自动提交/回滚。
最后的 asCallback(callback)
调用可确保 Promise 链中抛出的错误将传递给 callback
。您不需要单独处理每个 Promise 的错误,因为 Promise 链的所有错误都会冒泡。同样,如果从第二个 sql 查询(promise 链的最后一个)返回结果,则该结果将作为第二个参数传递给callback
。
关于javascript - Knex 交易 promise 警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41229715/
knex.raw(sql, bindings)和 knex.schema.raw(statement) . 似乎这两个函数具有不同的签名。 如果它们相等,我该如何使用 knex.schema.raw(
我有一些 Knex 迁移脚本,如下所示: 'use strict'; exports.up = function (knex) { return knex.schema .ha
我希望基本上在 Knex 中进行此类查询,但我无法使其正常工作: select distinct * from ( select *, 1 as rank from table1 where Wo
我想为 Knex 迁移中的主键设置默认值,但我遇到了问题。这是我最初的迁移: exports.up = (knex, Promise) => { return knex.schema.create
我发现有两种方法可以在迁移文件中编写 knex 迁移。 exports.up = function (knex) { return knex.schema .createTable
我正在使用 MSSQL,我有一个存储过程返回多个结果集(1 个用于数据,1 个用于记录计数)当我使用 knex.raw 调用此存储过程时,Knex 仅返回第一个结果集。如何使用 Knex + Node
我有一个表,当向其中添加新行时,所有现有行都需要更新。本质上,在一个“插入”完成之前,我不想让另一个“插入”发生。 所以我猜普通的行级锁或读锁是不够的,想在事务期间直接锁表。 有没有办法在 Knex
我正在尝试使用以下代码在迁移脚本中将列数据类型从日期修改为时间戳 knex.schema.alterTable('user', function(t) { t.timestamp('bifthda
我的 Knex 驱动程序出现间歇性错误: TimeoutError: Knex: 获取连接超时。游泳池可能已经满了。你错过了一个 .transacting(trx) 调用吗? 我猜,要么是我的 RDS
我有以下路线,我想获取与从第一个查询获得的 id 关联的总和 app.post('/VerEmpresas', function (req, res) { var r, dot, ide; k
在How to return a plain value from a Knex / Postgresql query? ,我询问了如何从 Knex 查询中获取列值,而没有包含列名的 JSON 对象。
我对 knex(和 node js)很陌生。如果存在,我需要编写插入,但我无法执行此操作。 下面不起作用,但有没有办法做到这一点? var val = "water"; knex('ingredien
有没有办法使用 Kenx 将 IF 语句添加到 SELECT 查询?假设我要执行以下查询: SELECT id, name, IF(grade<60,'Fail','Pass') AS examRes
我有一个关于 SQL 连接池的问题。我的团队正在我们的 Node 应用程序之一中使用 knex.js 库来进行数据库查询。应用程序不时需要切换数据库。因此,我的团队创建了一个初始化函数,该函数返回配置
我刚刚接触 knex,遇到了事务。我认为它很有用,因为它具有回滚功能。尝试使用它(参见下面的代码) await knex.transaction(trx => { knex.raw(delete fr
我正在为 Mysql 使用 Knex.js。我运行迁移并成功创建表。之后,当我通过此命令命令 knex seed:run 运行种子时,出现以下错误: Knex:warning - calling kn
我通过以下方式将 order by 绑定(bind)添加到 knex 原始查询。 -- Here userIds = [1,2,3] and dataOrder='DESC' knex.raw.que
尝试针对我的远程 postgres 数据库(不是本地主机)运行 knex seed:run 时出现以下错误:Knex:Error Pool2 - Error: connect ECONNREFUSED
我要在一个函数中对数据库执行五 (5) 项操作。我想将它们放入事务中,但我发现将每个都放入前一个操作的回调中有点奇怪。我怎样才能以优雅和可读的方式做到这一点? 最佳答案 Knex 具有内置的事务支持,
我正在尝试使用 Knex.js 查询生成器构建数据库迁移,但是我收到以下与外键关系相关的错误: Knex:warning - migrations failed with error: alter t
我是一名优秀的程序员,十分优秀!