Intellij Idea 警告 - 使用异步/等待“忽略返回的承诺”
Posted
技术标签:
【中文标题】Intellij Idea 警告 - 使用异步/等待“忽略返回的承诺”【英文标题】:Intellij Idea warning - "Promise returned is ignored" with aysnc/await 【发布时间】:2017-05-07 19:53:18 【问题描述】:我在 Node.js v7.3 的代码中使用 Express.js。在此我创建了一个User Router
,它将请求转发到我的User Controller
。
我在 User Controller
中使用 async/await 来执行异步调用。问题是 IntelliJ 给了我一个警告,说
从 login() 返回的 Promise 被忽略。
问题是我什至没有从 login()
方法返回任何东西。
这是代码 -
UserRouter.js
router.post('/login', function (req, res, next)
userController.login(req, res); // I get the warning here
);
UserController.js
exports.login = async function (req, res)
try
const verifiedUser = await someFunction(req.body.access_code);
let user = await User.findOrCreateUser(verifiedUser);
res.status(200).send(user);
catch (err)
res.status(400).send(success: false, error: err);
;
如果我只使用本机承诺编写相同的登录方法,那么我不会收到此警告。我在这里理解有什么问题还是 IntelliJ 有问题?
编辑 -
感谢@Stephen,我知道异步函数返回一个承诺,但如果 Intellij 确定异步函数没有返回任何内容并且没有显示该警告,因为当我链接 @987654327 时,这不是更好@ 在 login()
函数之后,它提供了一个 undefined
对象到 then 结果中。这意味着如果我们没有从 async 函数显式返回一些东西,那么 undefined 会被返回?
【问题讨论】:
当 promise 解析为undefined
时,IDE 会警告您,您忽略了它在什么时候解析或拒绝的事实。如果您可以将函数标记为“可以安全地忽略 this 的承诺”,那就太好了,这样您就不必在每个调用站点都将其标记为忽略。
【参考方案1】:
userController.login()
函数返回一个 Promise,但您没有通过使用它的 then()
函数对 Promise 的结果做任何事情。
例如:
userController.login(req, res).then(() =>
// Do something after login is successful.
);
或者在 ES2017 语法中:
await userController.login(req, res);
如果您实际上不想在那里做任何事情,我想您可以忽略警告。警告主要存在,因为没有在 promise 上使用 then()
函数通常是代码异味。
【讨论】:
这应该是答案!! OP 清楚地解释了为什么 IntelliJ 会以一种优雅的方式处理它。另一个选民的回答只是告诉你忽略它 那么,如果我在代码的一系列执行中不需要,那么忽略 promise 函数返回值是一种好方法吗? 如果你真的不在乎函数是成功还是失败,并且不想在 promise 解决后对返回值做任何事情,你可以放心地省略.then()
调用。
我通常会这样做let ignore = asyncFunction();
这使得 intelliJ 停止抱怨(另外,如果它被称为忽略,它也不会抱怨未使用的变量)。此外,这表明我明确地忽略了承诺,而不仅仅是忘记了它。
@MarkusZeller 这在功能上与原始问题不同。在最初的问题中,承诺被(故意)忽略了。使用 async/await 时,您不再忽略 promise,但 await 之后的任何语句实际上都会等待 promise 完成。【参考方案2】:
问题是我什至没有从 login() 方法返回任何内容。
声明为“异步”的函数根据定义返回一个 Promise。 例如见https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Statements/async_function
然而,IDEA 警告只是一种检查。您可以在警告上按“alt-enter, right”并更改检查级别以使警告消失。 检查属于“JavaScript -> 可能的错误”类别,名为“方法调用返回承诺的结果被忽略”。
【讨论】:
在 WebStrom 中,禁用 [Preferences] - [Editor] - [Inspection] - [JavaScript] - [Probable bugs] - [Result of method call return a promise is ignored]。 在 Idea 中,禁用 [Preferences] - [Editor] - [Inspection] - [JavaScript 和 TypeScript] - [Async 代码和 Promise] - [忽略返回 Promise 的方法调用结果]。 【参考方案3】:router.post('/login', function (req, res, next)
void userController.login(req, res); // I get the warning here
);
你应该使用“void”操作符。
【讨论】:
这是我认为的最佳答案。这正是void
的设计目的。 From MDN: void 用于“将产生值的表达式求值到需要求值为 undefined 的表达式的位置。”
如果我这样做,SonarLint 会生我的气,而不是 Critical javascript:S3735
""void" should not be used" with description "The void operator评估其参数并无条件返回未定义。它可以是在 ECMAScript 5 之前的环境中很有用,其中 undefined 可以重新分配,但通常,它的使用会使代码更难理解。”【参考方案4】:
如果你真的像我一样狂躁并且不需要then()
,但你需要警告消失,一个可能的解决方案是:
functionWithAsync.error(console.error);
【讨论】:
或functionWithAsync.catch(console.error);
与其他版本的 Promise(如 ionic 5.2 中的那个)。
您没有解释原因,但这是一个非常好的解决方案,因为它可以处理任何可能被吞并而不被抛出的内部拒绝。如果有人调用 promise.reject 而你没有等待或处理被拒绝的承诺,它就消失了。通常在我的代码中,我实际上想抛出这个错误以停止执行。
@AnthonyO。请您或其他人详细说明您对.catch()
的规范而不是.error()
?环顾四周,似乎 .catch() 现在已成为常态。【参考方案5】:
消除警告的另一种方法是定义一个空的then()
:
userController.login(req, res); // <- Get the warning here
userController.login(req, res).then(); // <- No warning
【讨论】:
谢谢!这非常适合 Ionic 模板,因此您不必忽略带有混乱 cmets 的警告或在 IDE 中禁用。【参考方案6】:我在 NodeJs 中使用 try catch(e)
,发现只需在函数末尾添加 Error()
即可修复警告。
完整代码:-
someArray.forEach(async (arrayValue) =>
try
const prodData = await myAsyncFunc(arrayValue);
catch(e)
console.error(`Error: $e`);
, Error());
【讨论】:
【参考方案7】:如果您只是想为任何 JetBrains 产品关闭此警告。前往
Preferences > Inspections > JavaScript and TypeScript | Async code and promises | Result of method call returning a promise is ignored
并关闭设置。
【讨论】:
【参考方案8】:functionWithAsync.catch();
在 Angular 中可以是:
private async someMethod()
await this.asyncMethod.catch();
【讨论】:
以上是关于Intellij Idea 警告 - 使用异步/等待“忽略返回的承诺”的主要内容,如果未能解决你的问题,请参考以下文章
Intellij IDEA 如何去掉 @Autowired 注入警告
去掉IntelliJ IDEA 中 mybatis 对应的 xml 文件警告
idea设置去掉IntelliJ IDEA 中 mybatis 对应的 xml 文件警告