Complementando um pouco a resposta do EstevamOt, já que você tá começando a estudar funções assíncronas.
Quando a gente trabalha com Promise e Callbacks a ideia é que estamos avisando pro "código": olha, isso aqui pode demorar um pouco, então ao invés de bloquear a execução de tudo pode ir fazendo o que precisa e quando eu terminar eu te aviso.
Então pegando como exemplo a função:
function pegaIdade() {
return new Promise(function (resolve, reject) {
const idade = Math.floor(Math.random() * 100);
if (idade) {
resolve(idade);
} else {
reject("Idade Inválida");
}
});
}
A função pegaIdade
faria alguma consulta a alguma API e retornaria uma Promise. A Promise aceita 2 funções de callback, uma que é executada quando a operação ocorre com sucesso (resolve
) e outra para quando tem erro na operação (reject
).
A Promise aceita, por meio de uma interface fluente, indicar o que será executado quando terminar. No caso de sucesso executará o then
e no caso de falha pulará direto para o catch
.
pegaIdade()
.then(idade => console.log(idade))
.catch(error => console.error(error))
O bom de usar Promise é que você pode executar todas de uma única vez e então ter só 1 callback pra executar após todas retornarem algo. Muito útil quando a ordem de execução de uma função não depende da outra.
Promise
.all([pegaIdade(), pegaIdade(), pegaIdade()])
.then(([idade1, idade2, idade3]) => {
console.log("idade1: " + idade1);
console.log("idade2: " + idade2);
console.log("idade3: " + idade3);
})
.catch(error => console.error(error))
Promise também permite encadeamento do retorno, para quando você precisa tratar o dado antes de ir pra próxima etapa.
pegaIdade()
.then((idade) => {
if (idade < 18) {
throw "Menores não permitidos"
}
return idade % 2 ? false : true;
})
.then(ePar => console.log(ePar))
.catch(error => console.error(error))
Quando fazemos esse encadeamento de then
é porque uma resposta depende de alguma chamada assíncrona. Mas ir encadeando um monte de then pode deixar o código meio confuso.
Aí entram o async/await marcando a função.
Dentro de uma função marcada com async
podemos indicar que vamos esperar a Promise executar e retornar o seu valor ao invés de aguardar a Promise chamar nossa callback. Isso fazemos com o await
. Desta forma quando temos várias chamadas a funções assíncronas e que uma chamada dependa da anterior fazemos um código mais linear ao invés de vários encadeamentos.
Mas quando fazemos desta forma o erro que a Promise dispara vira uma exceção. Por isso precisamos tratar com try...catch
.
async function reserva() {
try {
const idade = await pegaIdade();
if (idade < 18) {
throw "Menores não permitidos";
}
const reservaEfetuada = await efetuaReserva();
return reservaEfetuada
} catch (error) {
console.error(error);
return false;
}
}
Importante também ressaltar que quando marcamos uma função com async
estamos transformando ela numa Promise.