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 文件警告

Intellij IDEA中Mybatis Mapper自动注入警告的6种解决方案

如何去掉Intellij IDEA过多的警告 设置警告级别

Intellij idea 中如何做到像eclipse一样 未引用的包或未引用的方法在类文件中报黄色警告