Executando verificação de segurança...
2

Opa tudo bem Bruno? Seguinte, eu tecnicamente aprendi async/await na marra sem ordem nem nada, não estou dizendo que é o certo. Portanto, a diferença entre promise e try/catch, funcionalmente são a mesma coisa, mas a promise se torna um pouco diferente.

Try/catch

Esse método, ele é utilizado em casos sincronos onde não há a utilização de async/await, mas nada diz que você precisa utilizar esse método só nessa situação. No exemplo abaixo explico como funciona o resultado da função.

async function hello_world() {
  try {
    const request = await _api-response_
    return request;
  } catch (error) {
      return error;
    }
}

Nessa função, o resultado produzido será um return com os dados esperados - se der certo - ou um resultado com os erros. Se o resultado for o esperado e você, por exemplo receber um json, você conseguirá acessar o json sem precisar realizar outro passo, nesse caso, um .then que é necessário quando se tem uma promise sem async/await.

Promise

Essencialmente a ideia é a mesma que o try/catch, mas esse método é utilizado e recomendado para funções assíncronas como em apis próprias. Normalmente se pode utilizar sem a necessidade async/await, mas você precisará encadear estruturas .then/.catch para saber os resultados.

function minhaFunçao() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve("Hello");
        }, 2000);
    });

minhaFuncao()
    .then((result) => {
        console.log(result);
    })
    .catch((error) => {
        console.error(error);
    });

Neste exemplo, se você colocar a função (minhaFuncao) em um console, você perceberá que será mostrado: "Promise {<pending}". Nesse caso você não consegue saber o retorno da função, para saber você precisa realizar a estrutura de .then que mostra o resultado da promise. Entretanto, você pode evitar esse passos a mais utilizando o async/await para dizer ao request que você pode esperar as promises se resolverem e trazer o resultado esperado, sem a necessidade de fazer o .then/.catch.

Quando utilizar um ou outro?

Resumidamente, utiliza-se o método try/catch em situações síncronas que podem gerar erros que você queira tratar. Já a promise é utilizada, comumente, para funções assíncronas. Ou seja, essencialmente são a mesma coisa, são estruturas para tratar resultados diferentes, mas são utilizadas em contextos diferentes, como em contextos síncronos (try/catch) e assíncronos (promises). No fim, você pode utilizar try/catch em situações assícronas e promises em situações sincronas ou vice e versa, mas a utilizacão de promises em contextos assíncronos, torna a leitura do código mais limpa e clara demonstrando organização de código a outros programadores.

Carregando publicação patrocinada...
2

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:

/**
 * Imagina que é uma chamada a alguma API
 * 
 * @returns {Promise<number>}
 */
function pegaIdade() {
    return new Promise(function (resolve, reject) {
        const idade = Math.floor(Math.random() * 100);
        
        // Caso deu tudo certo
        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"
        }

        // Esse return jogará uma nova resposta que será executada pelo próximo then
        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.

/**
 * @returns {Promise<boolean>}
 */
async function reserva() {
    try {
        const idade = await pegaIdade();
        
        if (idade < 18) {
            throw "Menores não permitidos";
        }

        // Imagina que aqui retorna um boolean
        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.

1