Explicando Promises de uma forma didática
Vinicius
Posted on March 26, 2019
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:
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:
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:
- Executamos a Promise
promessaDeAlimentarGatos
- Se o retorno for resolvido (
resolve
), nossa função.then
será ativada e nos mostrará a mensagem'Meus gatos estão com Buchinho Cheio'
. - 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:
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:
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:
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.
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.
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.
Posted on March 26, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 27, 2024
November 6, 2024