Explicando Promises de uma forma didática
Tags: javascript, promise
Published: 2019-03-26 17:40:06

---
title: Explicando Promises de uma forma didática
published: true
description: O que são e como funcionam as promises.
tags: javascript, promise
---

## Introdução

Enquanto escrevemos nossos códigos, diariamente esbarramos - mesmo que de forma inconsciente - no que chamamos de **Promises** (ou Promessas). As similaridades entre o objeto de uma promise e uma promessa feita no dia-a-dia são maiores do que pensamos quando tratamos pelo fluxo que elas percorrem.

Quando prometemos algo para alguém, podemos cumprir esta promessa ou não. Em **JavaScript**, esse comportamento é muito parecido. Ao estabelecermos uma promise, este retorno pode ou não se concretizar - e assim definirmos uma decisão para esses casos (`resolve` ou `reject`).

## Iniciando pelo básico

Digamos que eu faça uma promessa aos meus gatos de alimentá-los todas as manhãs.

Em `JavaScript` teríamos:

```javascript
let promessaDeAlimentarGatos = new Promise(function(resolve, reject){
    let poteCheio = true;

    if(poteCheio) {
        resolve('Buchinho cheio');
    } else {
        reject('Fome');
    }
});
```

**Resultado:** `'Buchinho cheio'`.

Como na vida real, em `JavaScript` temos dois retornos chamados de `resolve` e `reject`. No exemplo acima, por `poteCheio` ser **verdadeiro**, meus gatos tiveram mais um dia de barriga cheia e muita preguiça.

Portanto, respeitando as condições, a `Promise` se resolveu com a mensagem `Buchinho cheio`. Se `poteCheio` fosse **falso**, meus gatos estariam com fome e a `Promise` rejeitaria com a mensagem `Fome`.

## Onde está a verdadeira utilidade

Como o resultado da `Promise` depende diretamente de cumprir ou não as condições, temos uma forma de aplicar este resultado fazendo bom uso disso.

Nossa `Promise` agora existe, então podemos executá-la e exibir uma mensagem de acordo com o resultado obtido, da seguinte forma:

```javascript
promessaDeAlimentarGatos.then(function(result){
    console.log('Meus gatos estão com ', result)
}).catch(function(result) {
    console.log('Meus gatos estão com ', result);
});
```

Dissecando este código temos o seguinte fluxo:

1. Executamos a Promise `promessaDeAlimentarGatos`
2. Se o retorno for resolvido (`resolve`), nossa função `.then` será ativada e nos mostrará a mensagem `'Meus gatos estão com Buchinho Cheio'`.
3. Se o retorno for rejeitado (`reject`), nossa função `.catch` será ativada e nos mostrará a mensagem `'Meus gatos estão com Fome'`.

E são as funções `.then` e `.catch` que nos trazem uma ótima aplicabilidade do uso das `Promises`.

## Encadeando Promises

Atualmente, tenho 3 gatos. Digamos que quero exibir quais gatos eu já enchi o pote de ração.

Como eu sou só um, eu teria de seguir uma linha para encher todos os potes.

Esta atividade pode ser transcrita para `JavaScript` da seguinte forma:

```javascript
let alimentarLuna = function() {
    return new Promise(function(resolve, reject) {
        resolve('Alimentei a Luna');
    });
}

let alimentarJulieta = function(message) {
    return new Promise(function(resolve, reject) {
        resolve(message + ', e' + alimentei a Julieta');
    });
}

let alimentarGatarina = function() {
    return new Promise(function(resolve, reject) {
        resolve(message + ' e ' + alimentei a Gatarina.');
    });
}
```

Temos acima, três promises que nos retornam quais gatas foram alimentadas. Mas pra isso, eu preciso primeiro encher o pote da primeira gata para passar para o pote da segunda gata.

Podemos transcrever isto para `JavaScript` da seguinte forma:

```javascript
alimentarLuna().then(function(result){
    return alimentarJulieta(result);
}).then(function(result){
    return alimentarGatarina(result);
});
```

O resultado seria impresso na tela desdobrando os resultados das promises

`Alimentei a Luna, e alimentei a Julieta e alimentei a Gatarina.`

Os resultados das promises foram concatenados e resultaram na frase completa ao fim do processo.

## Por que existem as Promises?

Pra isso, precisamos entender que `JavaScript` é uma linguagem **single-threaded**, ou seja, trabalha com apenas um caminho - *executa apenas uma linha de código em um determinado tempo*.

Para que nosso programa não travasse dependendo da resposta de um serviço, elaboramos as **Promises** - que rodam essa linha de código e convenientemente nos avisam quando esta execução foi encerrada.

Essa discussão pode ficar bem mais aprofundada, mas para nos mantermos no assunto, vou encerrar concluindo que as Promises existem para que os programas em `JS` possam buscar informações de serviços sem parar a aplicação por inteiro.

## Entendendo Promise.all e Promise.raise

As promises não necessariamente precisam rodar em sequência. Podemos, utilizando do exemplo, dividir as tarefas de alimentar as gatas com os outros 2 moradores de minha casa - de forma *simultânea*.

Assim trataríamos da seguinte forma:

```javascript
Promise.all([alimentarLuna(), alimentarJulieta(), alimentarGatarina()]).then(function(){
    console.log('Todas as gatas foram alimentadas');
});
```

Digamos que novas atividades aparecem a medida que os moradores finalizam as suas atividades, podemos usar `.raise` para notificar quando estas etapas forem se concluindo.

```javascript
Promise.raise([limparCaixa(), varrerPelos(), trocarAgua()]).then(function(){
    console.log('Um morador finalizou uma das atividades');
});
```

## Conclusão

Resumidamente, as `Promises` funcionam como nossas promessas. Elas podem ou não se concretizar, e com isso temos tratativas para um final positivo ou negativo deste resultado.

![Um breve esquema de como funcionam .then e .catch de acordo com o exemplo dos Gatos alimentados][scheme]

[scheme]: https://thepracticaldev.s3.amazonaws.com/i/lgdi4t57eb88bw2pnkae.png ".then e .catch explicados com o exemplo dos gatos alimentados"

Utilizar `.then` e `.catch` para tratar Promises encadeadas é um daqueles momentos que uma Promise brilha de verdade.

Espero que este breve texto te ajude, e se encontrar algo de errado em minhas palavras, fique a vontade para me corrigir. Atualizarei a publicação sempre que possível.