Entendendo Promises: Como funcionam e seus benefícios em JavaScript
Tags: javascript, promises, ecmascript, programming
Published: 2023-04-06 23:42:00

## Introdução
Esse é o nosso penúltimo artigo da série Ecmascript 6. Iremos tratar sobre `promises`. Esse tema será dividido em duas partes. Nessa primeira, iremos falar sobre conceitos importantes e benefícios. A ideia é compartilhar algumas anotações minhas durante a leitura do livro EcmaScript 6 Succinctly, que me permitiram compreender um pouquinho sobre `promises`.

## Compreensão

### Explicação sobre como as Promises funcionam

`Promises` fornecem um padrão de implementação para lidar com programação assíncrona em Javascript sem a necessidade de usar `callbacks`. Uma `promise` representa um valor que nós podemos lidar em algum momento no futuro.

Para ficar mais claro, imagine que você é uma criança que pediu ao seu pai uma bola de presente. Ele lhe diz que irá te dar uma bola, mas não pode te entregar imediatamente, pois precisa comprá-la na loja. Ele então promete que trará a bola para você assim que puder.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExMmIyZTJjM2Y5OWVlMDQzZThhZGE0ZDJhYjA0NGVhNTE4MDI4MmI3ZCZjdD1n/Cu7tfLe1edy3HE7JfC/giphy.gif">


Nesse exemplo, a `promise` é a promessa do pai de trazer a bola, que representa um valor (a bola) que você poderá lidar em algum momento no futuro (quando ele trouxer a bola para você).

### Benefícios do uso de Promises em relação a outros métodos assíncronos

As `promises` oferecem benefícios significativos em relação aos `callbacks`, por exemplo. Uma das principais vantagens é que o contrato da `promise` é imutável, ou seja, nenhum outro handler registrado pode alterar o valor.

Aqui está um exemplo de código JavaScript que ilustra como uma `promise` pode ser usada para garantir que o valor seja recebido independentemente de quando um handler for registrado para ele:

``` typescript
let promise = new Promise((resolve, reject) => {
  // simula um valor que será retornado após 1 segundo
  setTimeout(() => resolve("valor retornado"), 1000);
});

// registra um handler para a Promise após 2 segundos
setTimeout(() => {
  promise.then((valor) => {
    console.log(`Valor recebido: ${valor}`);
  });
}, 2000);

// registra outro handler para a Promise imediatamente
promise.then((valor) => {
  console.log(`Outro valor recebido: ${valor}`);
});
```
Neste exemplo, uma `promise` é criada com uma função que retorna um valor após 1 segundo. Em seguida, dois handlers são registrados para a `promise`, um imediatamente e outro após 2 segundos. No entanto, como o contrato da `promise` é imutável, o valor retornado nunca será alterado e, portanto, ambos os handlers receberão o mesmo valor.

Além disso, com as `promises`, temos a garantia de receber o valor, independentemente de quando nos registrarmos para recebê-lo, mesmo que já esteja resolvido. Isso contrasta com os `eventos`, uma vez que, quando um evento é acionado, não é possível acessar o seu valor em um momento posterior.

### E quando uma promessa não é cumprida?

Até agora, nós só resolvemos `promises`. Mas e quando rejeitamos uma? A rejeição de uma `promise` ocorre quando há algum problema para cumprir a promessa, como falha na conexão com um servidor ou algum erro no código.

Voltemos ao exemplo do pai e filho. Imagine que você é uma criança que pediu ao seu pai para ir ao parque de diversões. Ele concorda em levá-lo, mas diz que só poderá fazê-lo se não chover. No entanto, o tempo vira e começa a chover, o que significa que seu pai não pode cumprir sua promessa de levá-lo ao parque. Seu pai, então, rejeita sua promessa e explica que ele não pode cumprir o que havia prometido, pois as condições climáticas mudaram.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/gRnSZSRzOJeG4/giphy.gif">

Nesse exemplo, a `promise` é a promessa do pai de levá-lo ao parque, e o `reject` é a decisão de não cumprir a promessa devido a uma condição não satisfeita (o mau tempo). No contexto do código, você pode tratar essa situação, usando o método `catch()` na `promise`, que permite capturar o erro e tratar a rejeição.

``` typescript
const promise = new Promise((resolve, reject) => {
  const a = 10;
  const b = 'abc';
  if (typeof a === 'number' && typeof b === 'number') {
    resolve(a + b);
  } else {
    reject('Os valores precisam ser números!');
  }
});

promise.catch(error => {
  console.error(error);
});
```

## Conclusão

No geral, o uso de `promises` é uma forma eficiente e moderna de lidar com operações assíncronas em JavaScript. Comparado aos `callbacks`, as `promises` oferecem uma série de benefícios, como a imutabilidade do contrato da `promise` e a garantia de que receberemos o valor, mesmo se já tiver sido resolvido. 

Além disso, aprendemos que uma promessa pode ser rejeitada, quando alguma condição básica não é atendida. Uma boa prática é utilizar o método catch a fim de tratar o erro (aprenderemos mais sobre tratamento de erros no próximo artigo). 

Você já usou `promises` no seu código? Quando escrevia um código, tinha consciência do que estava fazendo? Deixa eu saber nos comentários, até a próxima!

## Para saber mais acesse:
- [ECMAScript 6 Succinctly](https://www.syncfusion.com/succinctly-free-ebooks/ecmascript-6-succinctly)