No Desenvolvimento Web nem tudo é instantâneo…
Por exemplo, quando você usa um serviço externo, ele pode levar alguns segundos para responder.
Ou talvez você esteja fazendo uma operação assíncrona…
Seja qual for o caso, vai precisar lidar com uma Promise JavaScript.
Então, se você nunca trabalhou com promises ou não sabe o que significa, continue lendo esse artigo para saber:
- O que é;
- Para que serve;
- E como utilizar.
O que é promise no javascript?
“Promise é um objeto criado para lidar com resultados de operações assíncronas…
Como a execução do JavaScript é ininterrupta, temos um problema quando nosso código depende do resultado de uma operação que não sabemos quanto tempo levará até ser completada.” – Diego Pinho, ECMAScript 6
Uma situação comum é quando usamos uma API externa em nossa aplicação.
Afinal, a solicitação é feita para outro servidor, e não sabemos quanto tempo ele vai levar para enviar uma resposta.
Mas enquanto isso, a execução do nosso código continua e precisa do resultado dessa operação.
Por exemplo, se tentarmos acessar o saldo de uma conta bancária antes que a requisição tenha sido concluída, não teremos o valor esperado:
Note que obtivemos o valor undefined
ao invés do saldo.
Esse tópico foi baseado no livro ECMAScript 6 do Diego Pinha, editora Casa do Código.
Os estados de uma promise
O objeto promise guarda a promessa de que, em algum momento, sua execução vai terminar e gerar um resultado.
Mas pode acontecer um erro durante a atividade…
E por conta disso, uma promise possui 3 estados:
- Pendente: estado inicial, quando está esperando a execução finalizar;
- Resolvido: a execução foi concluída com sucesso;
- Rejeitado: ocorreu um erro durante a execução.
Mas como passar de um estado para outro?
Construindo uma promise em javascript
O construtor da promise recebe uma função com 2 argumentos: resolve
e reject
:
var promise = new Promise((resolve, reject) => {
// Lógica da promise
});
Dessa forma, usamos os 2 parâmetros dentro da lógica da função para indicar quando a promise foi resolvida ou rejeitada:
var promise = new Promise((resolve, reject) => {
var result = true;
if(result) {
resolve("Executada com sucesso!");
} else {
reject("Ocorreu um erro...");
}
});
Veja que passamos uma string para resolve
e reject
, indicando que a lógica foi:
- “Executada com sucesso!”
- Ou “Ocorreu um erro…”
Porém podemos passar o que quisermos, desde informações do banco de dados até um objeto de erro…
var promise = new Promise((resolve, reject) => {
// Contém a operação realizada
// ...
// Retorna o estado
if(result) {
resolve(result);
} else {
reject(error);
}
});
E agora? Como usamos tudo isso?
Como usar uma promise
Você pode definir uma função para ser executada quando a promise é resolvida com sucesso ou rejeitada.
Para isso, você utiliza o then
e o catch
:
Quando a promise é resolvida sem problemas, o then
é acionado. Da mesma forma acontece com o catch
quando a promise é rejeitada.
Vejamos então como ficaria o exemplo do tópico anterior:
promise.then((data) => console.log(`resultado: ${data}`));
promise.catch((data) => console.log(`erro: ${data}`));
A variável result
simula o resultado de uma operação assíncrona.
Nesse caso o resultado foi positivo e o código irá mostrar no console a string:
resultado: Executada com sucesso!
Note que as funções then
e catch
recebem um parâmetro data
por padrão…
Assim podem recuperar os dados passados pela promise.
Por fim, ao alterar o result
para false
, o código vai retornar no console uma frase diferente:
erro: Ocorreu um erro...
Encadeando then e catch
Por último, podemos encadear as chamadas de then
e catch
, e assim obter um código mais limpo e de fácil leitura.
Por exemplo, ao invés de declarar os métodos then
e catch
um de cada vez, como fizemos antes, você pode fazer da seguinte maneira:
promise
.then((data) => console.log(`resultado: ${data}`))
.catch((data) => console.log(`erro: ${data}`));
Além disso, você pode encadear várias chamadas de then
. Assim um é executado depois do outro:
promise
.then((data) => console.log(`resultado: ${data}`))
.then((data) => console.log(`resultado 2: ${data}`))
.catch((data) => console.log(`erro: ${data}`));
Mas atenção ao usar o encadeamento de then
!
Note que, com a promise resolvida, o segundo resultado na saída do console possui o valor de undefined
, ao invés de “Executada com sucesso!” :
resultado: Executada com sucesso!
resultado 2: undefined
Isso acontece por que precisamos passar adiante o valor da variável data
disponível no primeiro then
.
E fazemos isso retornando o valor na função anterior:
promise
.then((data) => {
console.log(`resultado: ${data}`);
return data;
})
.then((data) => console.log(`resultado 2: ${data}`))
.catch((data) => console.log(`erro: ${data}`));
Agora, ao executar o código, as 2 mensagens são apresentadas corretamente.
resultado: Executada com sucesso!
resultado 2: Executada com sucesso!
Conclusão
O JavaScript possui vários recursos incríveis que facilitam muito a nossa vida…
E o objeto Promise é apenas um deles…
Para conhecer mais funcionalidades muito úteis como essa, recomendo que dê uma olhada no livro ECMAScript 6 do Diego Pinho.
Foi um dos poucos livros que li 2 vezes e valeu super a pena na minha opinião!
Hey,
o que você achou deste conteúdo? Conte nos comentários.
Referências:
Livro ECMAScript6
Training Center
Mozilla Docs
JavaScript Info
NodeJS Blog
JavaScript Tutorial