Pesquisa de site

javascript - Aviso do Intellij Idea - "Promessa retornada é ignorada" com async/await


Estou usando Express.js no meu código com Node.js v7.3. Nele, criei um User Router que encaminha as requisições para o meu User Controller.

Estou usando async/await dentro do Controlador de Usuário para fazer chamadas assíncronas. O problema é que o IntelliJ me dá um aviso dizendo que

A promessa retornada de login() está sendo ignorada.

A questão é que eu nem estou retornando nada do método login().

Aqui está o código -

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});
    }
};

Se eu escrever o mesmo método de login usando apenas promises nativas, então não recebo este aviso. Estou entendendo algo errado aqui ou o problema é do IntelliJ?

EDITAR -

Graças ao @Stephen, eu entendo que uma função async retorna uma promise, mas não seria melhor se o Intellij identificasse que nada está sendo retornado da função async e não mostrasse esse aviso, porque quando eu encadeio um .then() após a função login(), ele fornece um objeto undefined no resultado do then. Isso significa que, se não retornarmos algo da função async explicitamente, então undefined é retornado?

Resposta #1

Você deve usar o operador "void".

Do MDN: void é para "avaliar expressões que produzem um valor em lugares onde uma expressão que avalia para undefined é desejada."

router.post('/login', function (req, res, next) {
    void userController.login(req, res); // Warning will not be shown now
});

Resposta #2

A função userController.login() retorna uma promessa, mas você não está fazendo nada com o resultado da promessa utilizando sua função then().

Por exemplo:

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

ou na sintaxe ES2017:

await userController.login(req, res);

Se você na verdade não quer fazer nada lá, eu acho que pode simplesmente ignorar o aviso. O aviso está principalmente lá porque não usar a função then() em uma promessa geralmente é um sinal de problema no código.

Resposta #3

O fato é que eu nem estou retornando nada do método login().

Uma função declarada como "async" retorna uma Promise por definição. Veja por exemplo https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

No entanto, o aviso do IDEA é apenas uma inspeção. Você pode pressionar "alt-enter, certo" sobre o aviso e alterar o nível da inspeção para fazer o aviso desaparecer. A inspeção está na categoria "JavaScript -> Possíveis erros" e se chama "Resultado da chamada de método que retorna uma promessa é ignorado".

Resposta #4

se você é realmente maníaco como eu e o then() não é necessário, mas você precisa que o aviso desapareça, uma possível solução é:

functionWithAsync.error(console.error);

// or use a logger
functionWithAsync.error(log.error);

Resposta #5

outra maneira de se livrar do aviso é definindo um then() vazio:

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

Resposta #6

Se você simplesmente quiser desativar este aviso para qualquer um dos produtos da JetBrains, vá para

Preferências > Inspeções > JavaScript e TypeScript | Código assíncrono e promessas | Resultado da chamada de método que retorna uma promessa é ignorado e desligue a configuração.

Artigos relacionados