When calling an asynchronous function, is it also necessary to note the calling function as "async"?

Asked

Viewed 209 times

2

I have a question about asynchronous functions. I have the following function in my file models:

const login = async (email, password) => {
    código qualquer aqui...
};

And now I need to call this function in my controller file, in a new function, for example:

const loginController = async  (req, res) => {
     // veja que estou chamando a primeira função aqui
     await login.create()
};

My question is: does it make sense to use the async in function loginController to call the function login, or does not make a difference? It hinders something in the function login?

  • 2

    The question was not very clear to me (try edit it!)... :) You’re asking if it would be necessary to use the async in function loginController? If so, yes, it is mandatory, since use await within a function that is not marked as async evokes a SyntaxError.

  • 2

    Actually I’m asking if due to function login be asynchronous, the function loginController should also be, or I can leave it as a common function(synchronous).

1 answer

2


In Javascript, it doesn’t matter if you’re using callbacks, Promises or asynchronous functions (which are basically syntactic sugar for the promise API), asynchronous is like a "plague".

This means that whenever you use an asynchronous API, the rest of the code that used the function will be required to bear that responsibility, thereby becoming asynchronous as well. It’s like a contamination.

Don’t think this is bad because it is a "contamination", it is only a consequence of the asynchronous nature of language.

Therefore, if you have an asynchronous function (like the function login):

// Note que a função abaixo é assíncrona (`async`):
async function login(email, password) {
  // Código qualquer aqui...
};

Any function you call login has to deal with its asynchronous nature. And any function that call the function that called login also... It is, of course, an endless "contamination" upward (towards the call stack):

One way to deal with this asymchronism is to use the async and await the resolution of the promise that login returns using the operator await. Thus:

async function loginController(req, res) {
  // Estamos lidando com o assincronismo de `login` utilizando `await`.
  // Note que, para utilizar o `await`, você é *obrigado* a utilizar o `async`.
  const loggedIn = await login(email, password);

  if (loggedIn) {
    res.send('OK!');
  } else {
    res.send('Dados incorretos.');
  }
}

Another option is to deal with the promise directly using the method then.

function loginController(req, res) {
  login(email, password).then((loggedIn) => {
    if (loggedIn) {
      res.send('OK!');
    } else {
      res.send('Dados incorretos.');
    }
  });
}

Note that in the above case we do not use async in the calling function, but we deal with the asymchronism of login a little more explicitly using directly the promise API.

A slightly more complete example of how to handle the promise API directly:

async function a() {
  await delay(500);
  return 1;
}

// Podemos lidar com o assincronismo sem o `async`. Por exemplo:
function b() {
  // Note que a `Promise` deve ser retornada:
  return a().then((a) => a + 1);
}
 
// Nada impede de usar o `async` depois também:
async function c() {
  const result = await b();
  console.log('Resultado:', result);
}

c().then(() => console.log('Finalizado.'));

// Ignore (só para criar um efeito de "lentidão"):
function delay(t) {
  return new Promise((r) => setTimeout(r, t));
}

In short, you are not "obliged" to use the async. However, you must deal with the asymchronism. For this, you can use the async, the API of Promises directly, etc..

Browser other questions tagged

You are not signed in. Login or sign up in order to post.