TL;DR
Você vai ver alguns conceitos de programação assíncrona e como usar um objeto Promise do Javascript para executar tarefas assíncronas facilmente.
Você já se deparou com alguma promessa não cumprida? Ou já prometeu alguma coisa para si mesmo e não cumpriu? Bem vindo ao time! Uma promessa, mesmo que signifique um compromisso, é sempre uma incerteza sobre o futuro. É por isso que, até ser cumprida, uma promessa é só uma promessa. Quer ver um exemplo?
— “O Brasil vai melhorar!”
Essa todo mundo já ouviu. Vou usar esse exemplo para mostrar, de maneira bem simples, como um desenvolvedor pode lidar com essas tais promessas. Não as dos políticos. Outras que nós desenvolvedores podemos encontrar no dia a dia. Pense numa promessa como alguma coisa que está fora do seu controle, seja na vida, seja no código, que você nunca sabe se vai mesmo acontecer e pela qual você não pode simplesmente ficar esperando.
A vida como ela é
Na vida real funciona mais ou menos assim:
- Uma promessa é feita
- Ela pode ou não se cumprir
- Enquanto você não sabe o que vai acontecer, a vida segue em frente
- Quando a promessa é cumprida, normalmente você fica feliz porque tudo aconteceu como era esperado
- Quando ela não é cumprida, você faz algo a respeito ou simplesmente deixa pra lá
No final você tem uma conclusão: cumpriu ou não cumpriu. Enquanto isso não acontece, aquela promessa está pendente.
Baixando o nível
Que tal descrever isso em Javascript? (Ligando o modo programador. Nem todos os códigos a seguir estão prontos para serem executados. Vamos construir a promessa por partes).
var oBrasilVaiMelhorar = new Promise();
Já temos uma promessa, mas quem vai realizá-la? Precisamos de um executor:
var oBrasilVaiMelhorar = new Promise( /* executor */ function(resolve, reject) { ... } );
A partir daí a promessa pode ou não ser cumprida. Para isso o executor recebe duas funções que resolvem ou rejeitam a promessa, depois de fazer algum trabalho assíncrono. De agora em diante vamos usar essa terminologia.
Uma promessa é considerada resolvida quando é finalizada do jeito que era esperado. Caso contrário, ela é rejeitada.
Promessa rejeitada (ele está se referindo a outro Michel, o repórter)
https://amarildocharge.wordpress.com/2014/12/25/nao-cumpriu/
Então o que seria necessário para resolver ou rejeitar essa promessa? Vamos adicionar uma condição hipotética que vai definir o resultado:
var acabouCorrupcao = false; var oBrasilVaiMelhorar = new Promise ( function(resolve, reject) { if (acabouCorrupcao) { var resultado = { inflacao: 0, educacao: 10, corruptos: 'presos' }; setTimeout(function(){ resolve(resultado) }, 3000); } else { var motivo = Error('Os corruptos ainda estão soltos! :('); reject(motivo); } } );
É claro que na vida real as coisas são beeeeem mais complicadas mas a ideia é essa: uma promessa precisa ter algum valor, tem que trazer alguma coisa útil, mesmo que isso demore a acontecer. Quando algo sai errado, tem que haver um motivo. Isso é feito pelas funções resolve
e reject
.
Cumprindo a promessa
O último exemplo acima já pode ser executado mas não faz nada ainda. A promessa continua pendente. Agora precisamos esperar até que ela seja resolvida ou rejeitada, certo?
Errado! Lembra do que eu disse lá em cima? A vida não para por causa de uma promessa que pode nunca se realizar. Pelo menos não deveria. Nós só precisamos definir o que vai ser feito, dependendo do resultado. Podemos acrescentar este código:
Dica: você pode executar o código no CodePen.
console.log('O Brasil vai melhorar!'); // promessa feita oBrasilVaiMelhorar .then(function(valor) { console.log('Agora vai! :)'); console.log(valor); }) .catch(function(motivo) { console.log('Só que não: ' + motivo.message); });
Dica: experimente mudar o valor de acabouCorrupcao para true e veja o que acontece.
Quando a promessa for resolvida, o que foi definido no método then
será executado para tratar o valor retornado. Este valor pode ser até uma outra promessa, como vamos ver depois. Mas quando ela for rejeitada, o método catch
recebe o motivo, que é um erro. O que vier depois não precisa esperar o executor terminar e o fluxo segue normalmente.
Ou seja: tudo aquilo que eu listei no início falando sobre como são as promessas na vida real foi satisfeito.
Isso foi só o começo. A segunda parte deste post vai mostrar algumas definições e dar dicas de como escrever um código mais limpo, mesmo sendo um pouco mais complexo. Siga o blog para receber as atualizações.
Saiba mais
Este post foi extraído de uma seção do Curso Progressive Web Apps. Nele você vai aprender como construir uma aplicação web com vários recursos que antes só existiam em apps nativos. Entre para saber mais.
Quero criar meu primeiro app
Links úteis
https://github.com/domenic/promises-unwrapping/blob/master/docs/states-and-fates.md
https://developers.google.com/web/fundamentals/getting-started/primers/promises?hl=pt-br
https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise
Muito bom o post, achei muito legal a analogia de promessas com o javascript, parabéns!
CurtirCurtir
Obrigado Igor!
CurtirCurtir