gpt4 book ai didi

JavaScript promise : UnhandledPromiseRejectionWarning

转载 作者:太空宇宙 更新时间:2023-11-04 03:12:44 25 4
gpt4 key购买 nike

我是 Javascript Promise 的新手。我正在尝试以基于 Promises 的方式执行 MySQL 查询,我已经挠头半个小时了,但我仍然找不到这段代码中的问题。我正在使用this article作为引用。

mysql文件

const mysql = require('mysql')
const Config = require('./Config.js');

let connection = mysql.createPool({
connectionLimit: Config.mysql.connectionLimit,
host: Config.mysql.host,
user: Config.mysql.user,
password: Config.mysql.password,
database: Config.mysql.database,
multipleStatements: true,
});

module.exports = {
query: function(query, binds) {
return new Promise((resolve, reject)=>{
connection.query(query, binds, (error, ret)=>{
if(error)
return reject(error);
else
resolve(ret);
})
})
},

close: function() {
return new Promise((resolve, reject)=>{
connection.end((error)=>{
if(error)
return reject(error);
else
resolve();
});
});
}
}

实际脚本

const Mysql = require('mysql file');

try {

Mysql.query("SELECT `password` \
FROM `m_users` \
WHERE `email` = ?",
['user@domain.tld'])
.then(ret=>{
if(ret.email)
return res.send({
params: req.body,
message: 'Email address has already been taken.',
})
})
.catch(error=>{
throw error;

})

catch( e )
{
console.log(e); // is never reached
}

抛出错误永远不会被触发。相反,在我的 Node 控制台中,我收到以下错误:

(node:8684) UnhandledPromiseRejectionWarning: Error: ER_NO_SUCH_TABLE: Table 'forge.m_users' doesn't exist

........backtrace here .......

(node:8684) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

我知道该表不存在。我有兴趣找出为什么 .catch 不处理该错误。我究竟做错了什么? :/

最佳答案

这是一种反模式(但到目前为止您并不是第一个这样做的人!):

.catch(error=>{
throw error;

})

这意味着“创建一个新的 Promise”(因为 catch 创建了一个 Promise)“如果原始 Promise 被拒绝,则以完全相同的拒绝原因(error)拒绝它。”所以它基本上是一个空操作,它不做任何事情。它的 promise 相当于:

try {
// something
} catch (error) {
throw error;
}

由于它不执行任何操作,请考虑一下如果没有它,代码会是什么样子 - 该代码违反了 Promise 的基本规则之一,即“处理拒绝或将链传递给其他会执行的操作”。 :-)

如果您想处理拒绝,请不要从 catch抛出:

Mysql.query("SELECT `password` \
FROM `m_users` \
WHERE `email` = ?",
['user@domain.tld'])
.then(ret=>{
if(ret.email) {
return res.send({
params: req.body,
message: 'Email address has already been taken.',
});
}
})
.catch(error=>{
// Use `error` here without `throw`ing -- report it, put it in a log, etc.
});

在问题的更新中,您表明您的所有代码都使用 try/catch 中的 promise :

try {
Mysql.query(/*...*/)
.then(/*...*/)
.catch(error=>{
throw error;
});
}
catch( e )
{
console.log(e); // is never reached
}

在非async函数中,try/catch无法捕获promise拒绝,因为当promise被拒绝时,执行已经离开try block 。直接使用 Promise 时,您可以使用 catch 方法。或者您使用async函数(更多内容见下文)。

<小时/>

旁注:Node.js 对 async 函数的支持已经有一段时间了,这往往编写起来更简单一些。在 async 函数中,您的代码可以是:

// Within an `async` function
try {
const ret = await Mysql.query("SELECT `password` \
FROM `m_users` \
WHERE `email` = ?",
['user@domain.tld']);
if(ret.email) {
return res.send({
params: req.body,
message: 'Email address has already been taken.',
});
}
} catch (error) {
// Use `error` here without `throw`ing -- report it, put it in a log, etc.
}

Using async at the top level of a module也即将推出...

<小时/>

在您提出的评论中:

I'm building an MVC API and I run more promise-based procedures in the same controller method. I'd like to return a message once an exception has been encountered and stop continuing the execution of the next other promised-based procedures. I'm bound to using async/await method or is there another way?

如果您不想,则不必使用async/await,不;它们只是让事情变得更简单(在我看来)。

如果您不想使用async/await,请在履行回调中传递then返回下一个操作的 promise 。这使得 Promise then 根据下一个操作的 Promise 执行或拒绝 - 用 Promise 术语来说,它then 的 Promise 解析为 下一个操作的 Promise。

代码有 1024 个字,因此:

doSomethingAsync()
.then(value => {
// ...use `value`, then
return doSomethingElseAsync();
})
.then(() => {
// ...
return doYetAnotherAsyncThing();
})
.catch(error => {
// Handle/report error here
});

如果任何 Promise 被拒绝,则将跳过任何后续的履行处理程序,并触发最后的拒绝处理程序(通过 catch 添加)。

这大致是此同步代码的 promise 版本:

try {
const value = doSomethingSync();
// ...use `value`, then
doSomethingElseSync();
// ...
doYetAnotherSyncThing();
} catch (error) {
// Handle/report error here
}

关于JavaScript promise : UnhandledPromiseRejectionWarning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60476055/

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