O que são promises (promessas) em JavaScript?

Promises, ou promessas, são um recurso do JavaScript que foi introduzido na versão ECMAScript 6 (ES6) para lidar com operações assíncronas de forma mais limpa e eficiente.

Uma promise é basicamente um objeto que representa um valor que pode estar disponível agora, no futuro ou talvez nunca. Ela é usada para lidar com operações assíncronas, como solicitações de rede, leitura/gravação de arquivos e consultas a banco de dados, entre outras.

As promises têm dois estados principais: pendente (pending) e resolvida (fulfilled) ou rejeitada (rejected). Quando uma promise é criada, ela está no estado pendente. A partir desse ponto, ela pode passar para os estados resolvida ou rejeitada, dependendo do resultado da operação assíncrona.

Uma promise é resolvida quando o resultado da operação assíncrona é bem-sucedido e um valor é retornado. Por exemplo, em uma chamada de API, a promise será resolvida quando os dados solicitados forem recebidos com sucesso.

Por outro lado, uma promise é rejeitada quando ocorre um erro ou uma exceção durante a operação assíncrona. Nesse caso, um motivo de rejeição é retornado, geralmente uma mensagem de erro.

Para utilizar uma promise, podemos encadear métodos de forma síncrona, como then() e catch(). O método then() é usado para lidar com o caso de sucesso, recebendo o resultado resolvido da promise como argumento. O método catch() é utilizado para tratar erros, recebendo o motivo de rejeição da promise como argumento.

Aqui está um exemplo de como podemos utilizar promises em JavaScript:

const getUserData = () => {
  return new Promise((resolve, reject) => {
    // Simulando uma operação assíncrona com timeout
    setTimeout(() => {
      const userData = { name: 'John', age: 30 };
      resolve(userData); // Resolvendo a promise com os dados do usuário
    }, 2000);
  });
};

getUserData()
  .then((result) => {
    console.log(result); // { name: 'John', age: 30 }
  })
  .catch((error) => {
    console.error(error);
  });

Neste exemplo, criamos uma função getUserData() que retorna uma promise. Dentro dessa promise, simulamos uma operação assíncrona com um timeout de 2 segundos. Quando o timeout é concluído, resolvemos a promise com os dados do usuário.

Em seguida, utilizamos o método then() para receber o resultado resolvido da promise e exibimos os dados do usuário no console. Se ocorrer algum erro durante a operação assíncrona, o método catch() será acionado e exibirá o motivo da rejeição no console.

As promises são muito úteis para lidar com operações assíncronas em JavaScript, pois permitem escrever um código mais legível e escalável. Eles substituem a necessidade de utilizar callbacks aninhados, conhecido como callback hell, melhorando a manutenibilidade do código.