Introdução
Promessas em Javascript podem ser desafiadoras de entender. Portanto, gostaria de escrever a maneira como entendo as promessas.
Entendendo Promessas
Uma Promessa em resumo:
“Imagine que você é uma criança. Sua mãe promete que vai te dar um novo telefone na próxima semana.”
Você não sabe se vai receber aquele telefone até a próxima semana. Sua mãe pode realmente comprar um telefone novo para você, ou ela não compra.
Isso é uma promessa. Uma promessa tem três estados. Eles são:
- Pendente: Você não sabe se vai receber aquele telefone
- Cumprida: A mãe está feliz, ela compra um telefone novo para você
- Rejeitada: A mãe está infeliz, ela não compra um telefone para você
Criando uma Promessa
Vamos converter isso para JavaScript.
O código é muito expresso por si próprio.
Abaixo é como uma sintaxe de promessa parece normalmente:
Consumir Promessas
Agora que temos a promessa, vamos consumirla:
Vamos executar o exemplo e ver o resultado!
Demo: https://jsbin.com/nifocu/1/edit?js,console
Encadeamento de Promessas
Promessas são encadeáveis.
Digamos que você, a criança, prometa a um amigo que vai mostrar a eles o novo telefone quando sua mãe comprar um para você.
Isso é outra promessa. Vamos escrevê-la!
Notas: Podemos encurtar o código acima escrevendo da seguinte forma:
Vamos encadear as promessas. Você, a criança, só pode iniciar a promessa showOff
após a promessa willIGetNewPhone
.
Assim é como você pode encadear a promessa.
Promessas são Assíncronas
Promessas são assíncronas. Vamos registrar uma mensagem antes e depois de chamarmos a promessa.
Qual é a sequência de saída esperada? Você pode esperar:
1. before asking Mom
2. Hey friend, I have a new black Samsung phone.
3. after asking mom
No entanto, a sequência de saída real é:
1. before asking Mom
2. after asking mom
3. Hey friend, I have a new black Samsung phone.
Você não pararia de brincar enquanto esperava pela promessa da sua mãe (o novo telefone). Isso é algo que chamamos de assíncrono: o código será executado sem bloquear ou esperar pelo resultado. Qualquer coisa que precise esperar pela promessa para prosseguir é colocada em .then
.
Aqui está o exemplo completo em ES5:
Promessas em ES5, ES6/2015, ES7/Next
ES5 – Maioria dos navegadores
O código de demonstração é viável em ambientes ES5 (todos os principais navegadores + NodeJs) se você incluir a biblioteca de promessas Bluebird. Isso porque o ES5 não suporta promessas prontas para uso. Outra famosa biblioteca de promessas é o Q por Kris Kowal.
ES6 / ES2015 – Navegadores modernos, NodeJs v6
O código de demonstração funciona imediatamente porque o ES6 suporta promises de forma nativa. Além disso, com funções ES6, podemos simplificar ainda mais o código com uma função de seta e usar const
e let
.
Aqui está o exemplo completo em código ES6:
Note que todos os var
foram substituídos por const
. Todas as function(resolve, reject)
foram simplificadas para (resolve, reject) =>
. Há vários benefícios que vêm com essas mudanças.
ES7 – Async/Await
O ES7 introduziu a sintaxe async
e await
. Isso torna a sintaxe assíncrona mais fácil de entender, sem os .then
e .catch
.
Reescreva nosso exemplo com a sintaxe ES7:
Promessas e Quando Utilizá-las
Por que precisamos de promessas? Como era o mundo antes das promessas? Antes de responder a essas perguntas, vamos voltar aos fundamentos.
Função Normal VS Função Assíncrona
Vamos analisar esses dois exemplos. Ambos os exemplos realizam a adição de dois números: um adiciona usando funções normais e o outro adiciona remotamente.
Função Normal para Adicionar Dois Números
Função Assíncrona para Adicionar Dois Números
Se você adicionar os números com a função normal, obtém o resultado imediatamente. No entanto, quando você faz uma chamada remota para obter o resultado, precisa esperar, e não pode obter o resultado imediatamente.
Você não sabe se vai obter o resultado porque o servidor pode estar inativo, lento na resposta, etc. Você não quer que todo o seu processo seja bloqueado enquanto espera pelo resultado.
Chamar APIs, baixar arquivos e ler arquivos são algumas das operações assíncronas comuns que você realizará.
Você não precisa usar promessas para uma chamada assíncrona. Antes das promessas, usávamos callbacks. Callbacks são uma função que você chama quando obtém o resultado de retorno. Vamos modificar o exemplo anterior para aceitar um callback.
Ação Assíncrona Subsequente
Em vez de adicionar os números um de cada vez, queremos adicionar três vezes. Em uma função normal, faríamos isso:-
Assim é como fica com callbacks:
Demo: https://jsbin.com/barimo/edit?html,js,console
Essa sintaxe é menos amigável para o usuário devido aos callbacks aninhados profundamente.
Evitando Callbacks Aninhados Profundamente
Promessas podem ajudar a evitar callbacks aninhados profundamente. Vamos ver a versão com promessas do mesmo exemplo:
Com promises, nivelamos o callback com .then
. De certa forma, parece mais limpo porque não há aninhamento de callbacks. Com a sintaxe async
do ES7, você poderia melhorar ainda mais este exemplo.
Observables
Antes de se decidir por promises, existe algo que surgiu para ajudá-lo a lidar com dados assíncronos chamado Observables
.
Vamos analisar o mesmo exemplo escrito com Observables. Neste exemplo, usaremos RxJS para os observables.
Os Observables podem fazer coisas mais interessantes. Por exemplo, adicionar a função delay
de 3 segundos
com apenas uma linha de código ou tentar novamente, permitindo que você repita uma chamada um certo número de vezes.
Você pode ler um dos meus posts sobre RxJs aqui.
Conclusão
Familiarizar-se com callbacks e promises é importante. Entenda-os e use-os. Não se preocupe com Observables por enquanto. Todos os três podem influenciar seu desenvolvimento dependendo da situação.
Source:
https://www.digitalocean.com/community/tutorials/understanding-javascript-promises