gpt4 book ai didi

javascript - Knex 交易 promise 警告

转载 作者:行者123 更新时间:2023-11-28 05:12:40 25 4
gpt4 key购买 nike

我在使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com