Na primeira parte você viu que uma promessa pode te ajudar a entender como funcionam num software as operações que devolvem um valor apenas no futuro. Viu também como processar o resultado e tratar os erros dessas operações, as promessas ou Promises. Essa abstração facilita muito na hora de programar. Agora você vai entender melhor alguns conceitos e ver como tornar o código mais limpo.
Definições
Estamos falando de programação assíncrona. No desenvolvimento de software sempre encontramos coisas que não dependem de nós, como uma conexão com um servidor ou o processamento de um arquivo, por exemplo.
Você não tem garantia de que aquele recurso vai estar disponível ou de que o processamento vai ser concluído com sucesso. Tudo que você tem é uma promessa, “um valor que pode estar disponível agora, no futuro ou nunca” (Mozilla). Ela representa “a eventual conclusão ou falha de uma operação assíncrona” (Mozilla). E por ser assíncrona, seu algoritmo pode continuar sem que ela termine. Basta que você trate o resultado quando a operação terminar, se terminar.
Se você tem que executar alguma operação possivelmente demorada e que pode dar erro, uma Promise pode te ajudar, desde que o seu processamento seja assíncrono.
Uma promessa atrás da outra
Até agora nós só definimos duas possibilidades para quando a tarefa terminar: o then
e o catch
. Só há um desfecho possível: resolvida ou rejeitada, nunca os dois. Mesmo que haja várias condições para determinar o resultado. Mas nós também podemos disparar outras promessas em seguida.
Suponha que você queira acessar a web e, em seguida, salvar a resposta num banco de dados, tudo assíncrono. Seria um bom caso de uso para encadear promessas, ou seja, executar uma com base no resultado da outra.
Vamos incrementar o exemplo do post anterior.
var protestar = function (motivo) { var mensagem = 'Vamos protestar porque ' + motivo.message; return Promise.reject(Error(mensagem)); }; console.log('O Brasil vai melhorar!'); // promessa feita oBrasilVaiMelhorar .then(function(valor) { console.log('Agora vai! :)'); console.log(valor); }) .catch(protestar); // se a promessa não se realizar, protestar .catch(function(motivo) { console.log('Só que não: ' + motivo); });
A função protestar
pega o erro da promessa anterior e retorna outra promessa. Isto é necessário para poder continuar o encadeamento de chamadas de then
e catch
. Esta cadeia pode continuar indefinidamente se cada função na fila retornar outra promessa, como no exemplo. Essa é uma das grandes vantagens em programar usando promises ao invés de callbacks.
Pegando atalhos
Na função protestar
, ao invés de criar explicitamente uma new Promise()
, como na primeira versão do código, usamos Promise.reject()
. Ele retorna uma nova promessa que será rejeitada com o valor fornecido. Da mesma forma, para devolver uma promessa que será resolvida, você pode retornar Promise.resolve()
. Portanto, as duas formas abaixo são equivalentes:
var protestar = function(motivo) { return Promise.reject(Error('Vamos protestar porque ' + motivo.message)); }; // equivale a var protestar = function(motivo) { return new Promise( function(resolve, reject) { reject(Error('Vamos protestar porque ' + motivo.message)); } ) };
Dica: note que não usei resolve
aqui. Nem resolve
nem reject
são obrigatórios mas ao menos um deles tem que aparecer.
Outra dica: no promisejs.org tem uma página só com padrões para tornar o código com promises mais simples.
Resumindo
Até aqui você viu que uma promessa:
- Tem três estados: pendente, resolvida ou rejeitada
- Está resolvida quando a ação relacionada a ela teve sucesso
- Está rejeitada quando a ação relacionada a ela falhou
- Está pendente quando não foi resolvida nem rejeitada
- Pode ser encadeada com outras promessas
- Sempre é assíncrona
Na terceira parte vamos usar um exemplo muito comum, presente em grande parte das páginas na web: como implementar uma requisição Ajax na forma de uma promessa.
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
1 Comentário