Intellij Idea警告 - 使用aysnc/await忽略"返回的Promise"

Jyo*_*ngh 46 javascript intellij-idea node.js async-await es6-promise

我在我的代码中使用Express.jsNode.js v7.3.在这里我创建了一个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
});
Run Code Online (Sandbox Code Playgroud)

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});
    }
};
Run Code Online (Sandbox Code Playgroud)

如果我只使用本机承诺编写相同的登录方法,那么我不会收到此警告.我在这里理解错误或者IntelliJ有错吗?

编辑 -

感谢@Stephen,我知道async函数会返回一个promise,但如果Intellij发现没有从async函数返回任何内容并且没有显示该警告,那就不会更好了,因为当我.then()login()函数之后链接a时,它undefined在then结果中提供一个对象.这意味着如果我们不显式地从异步函数返回一些东西,那么返回undefined?

Ste*_*ich 38

问题是我甚至没有从login()方法返回任何东西.

声明为"async"的函数按定义返回Promise.请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

然而,IDEA警告只是一次检查.您可以在警告上按"alt-enter,right"并更改检查级别以使警告消失.检查位于"JavaScript - >可能的错误"类别中,并命名为"返回承诺的方法调用结果被忽略".

  • 在WebStrom中,禁用[首选项] - [编辑器] - [检查] - [JavaScript] - [可能的错误] - [忽略返回承诺的方法调用的结果]。 (8认同)
  • 在Idea中,禁用[首选项] - [编辑器] - [检查] - [JavaScript和TypeScript] - [异步代码和承诺] - [忽略返回承诺的方法调用的结果]。 (4认同)
  • 如果 JetBrains 能有一个相当于 `// eslint-disable-line ...` 的东西就好了。有吗? (3认同)

Rob*_*bba 33

userController.login()函数返回一个promise,但是你没有通过利用它的then()函数对promise的结果做任何事情.

例如:

userController.login(req, res).then(() => {
    // Do something after login is successful.
});
Run Code Online (Sandbox Code Playgroud)

或者在ES2017语法中:

await userController.login(req, res);
Run Code Online (Sandbox Code Playgroud)

如果你真的不想在那里做任何事情,我想你可以忽略警告.警告主要是因为没有then()在承诺上使用函数通常是代码气味.

  • 我通常会做“ let ignore = asyncFunction();”,这会使intelliJ停止抱怨(而且如果它被称为ignore,它将不会抱怨未使用的变量)。另外,这表明我明确地忽略了诺言,而不仅仅是忘记了诺言。 (4认同)
  • 这应该是答案!!OP清楚地说明了IntelliJ为什么要以一种优雅的方式来处理它。其他选民的答案只是告诉您忽略它 (2认同)
  • 那么,如果在我的代码执行系列中不需要,那么忽略承诺函数返回值是一种好方法吗? (2认同)
  • @MarkusZeller,这在功能上与最初的问题不同。在最初的问题中,承诺被(故意)忽略了。当使用 async/await 时,您不再忽略 Promise,但在等待之后的任何语句实际上都会等待 Promise 完成。 (2认同)

小智 20

router.post('/login', function (req, res, next) {
    void userController.login(req, res); // I get the warning here
});
Run Code Online (Sandbox Code Playgroud)

您应该使用“void”运算符。

  • 这是我认为最好的答案。这正是“void”的设计目的。[来自 MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void#description): void 用于“计算产生值的表达式需要评估为未定义。” (3认同)
  • 如果我这样做,SonarLint 会生我的气,并用“Critical javascript:S3735”“不应使用”“void””和描述“The void 运算符评估其参数并无条件返回未定义。它在 ECMAScript 之前的版本中很有用5 环境中,未定义可以重新分配,但一般来说,它的使用会使代码更难理解。” (2认同)

Nat*_*ney 9

如果您只是想关闭任何 JetBrains 产品的此警告。去

Preferences > Inspections > JavaScript and TypeScript | Async code and promises | Result of method call returning a promise is ignored并关闭设置。


win*_*ter 7

如果您真的像我一样狂躁,并且then()不是必需的,但是您需要警告来消除,那么可能的解决方案是:

functionWithAsync.error(console.error);
Run Code Online (Sandbox Code Playgroud)

  • 或与其他版本的Promise(例如ionic 5.2中的版本)一起使用“ functionWithAsync.catch(console.error);”。 (6认同)
  • @安东尼奥。您或其他人能否详细说明您对“.catch()”而不是“.error()”的规范?环顾四周,似乎 .catch() 现在已经成为常态。 (2认同)

Ale*_*lva 7

摆脱警告的另一种方法是定义一个空then()

userController.login(req, res); // <- Get the warning here

userController.login(req, res).then(); // <- No warning


Joe*_*ene 5

try{} catch(e){}在 NodeJs 中使用,发现只需添加Error()到函数的末尾修复警告。

完整代码:-

someArray.forEach(async (arrayValue) => {
    try {
        const prodData = await myAsyncFunc(arrayValue);
    } catch(e) {
        console.error(`Error: ${e}`);
    }
}, Error());
Run Code Online (Sandbox Code Playgroud)