Neste artigo você vai aprender a como utilizar Promises em JavaScript, e também todos os métodos que este recurso possui
Fala programador(a), bora aprender mais sobre Promises e seus métodos: then, catch, all, race e outros!
Conteúdo também disponível em vídeo:
O que são as Promises?
Promises são como promessas da vida real, um código é executado esperando alguma resposta
Nós prometemos que alguma resposta será retornada, baseada na execução de algumas linhas de código
Alguns recursos de JavaScript retornam Promises, com a Fetch API, que serve para realizar requisições assíncronas
O bom deste retorno padrão de promessas é que utilizamos sempre os mesmos métodos, para dar continuidade e evidenciar erros, por exemplo
Como criar uma Promise?
Precisamos instanciar uma classe, que vai receber uma função anônima com dois parâmetros
- resolve: Que é retornado quando há um sucesso na promessa, então podemos inserir algo neste método para utilizar no código;
- rejected: Que é retornado quando um erro acontece, da mesma maneira que em resolve podemos colocar algo como parâmetro;
Normalmente as Promises são utilizadas para execução de algum código que pode demorar algum tempo
E isso é executado de forma assíncrona, sem que trave o restante do código
Veja um exemplo de Promise:
const myPromise = new Promise((resolve, reject) => { const nome = "Matheus" if(nome === "Matheus") { resolve("Usuário Matheus encontrado!") } else { reject("O usuário Matheus não foi encontrado!") } });
Criamos uma Promise que verifica um nome, isso na prática não seria necessário
Provavelmente esse nome viria de uma requisição para um banco de dados
E então a validação seria realizada
E como podemos executar uma Promise?
Para executar uma Promise vamos utilizar um método de encadeamento, chamado then
O then pode ser utilizado para finalizar uma Promise ou para dar continuidade, veja:
myPromise.then((data) => { console.log(data) // "Usuário Matheus encontrado!" })
Desta maneira temos a continuidade da Promise, nos retornando o resultado esperado
Mas não é só isso que podemos fazer, podemos continuar encadeando then’s
E manipular o resultado, por exemplo
Veja:
myPromise.then((data) => { return data.toLowerCase() }).then((fraseModificada) => { console.log(fraseModificada); // "usuário matheus encontrado!" })
Aqui utilizamos um then para manipulação de dados, alterando todas as letras da frase pra letras minúsculas
Este é um exemplo bem comum de como utilizar Promises em situações reais
E se mudarmos o valor do nome, lá na definição da promessa caímos no catch
Que é um outro método, onde podemos receber as mensagens de erro, quando algo deu errado na nossa Promise
Veja:
const myPromise = new Promise((resolve, reject) => { const nome = "João" if(nome === "Matheus") { resolve("Usuário Matheus encontrado!") } else { reject("O usuário Matheus não foi encontrado!") } }); myPromise.then((data) => { return data.toLowerCase(); }).then((fraseModificada) => { console.log(fraseModificada); }).catch((response) => { console.log(response); // "O usuário Matheus não foi encontrado!" })
O nome foi alterado para João, então a Promise caiu no else
Ativando o método reject, dando então abertura para utilizarmos o catch
Que colocamos ao final dos then’s
Veja que a mensagem do else que foi impressa como resultado final
Então desta maneira podemos: processar promessas, encadear modificações e também tratar os erros que acontecem na execução
Executando várias Promises
Temos duas maneiras de executar vários promessas, uma que vai finalizar quando todas as promessas acabarem
Ou seja, há um tempo x de aguardo, determinado pela promise mais demorada
E então recebemos todas as respostas de uma vez, este método é o all
Veja um exemplo:
const p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Resolveu o timeout') }, 2000) }) const p2 = new Promise((resolve, reject) => { resolve('Promessa 2 resolvida!') }) const p3 = new Promise((resolve, reject) => { resolve('Promessa 3 resolvida!') }) const resolveAll = Promise.all([p1, p2, p3]).then((data) => { console.log(data) // todas as mensagens })
Note que precisamos invocar o método all na classe Promise, que é de onde ele é originado
É também necessário passar o array de promessas a serem resolvidas, neste caso temos três
E um detalhe importante, a resposta só será enviada após 2 segundos, que é o timeout da primeira
Ou seja, receberemos algum retorno após esperar a execução da mais demorada, e este é um bom exemplo de uma requisição externa
Isso por que não sabemos quanto tempo ela demorará a responder, e as duas outras são imeadiatas, pois o código é apenas um resolve
Além do all há outro método, que é o race
Da mesma forma que em all, vamos passar um array de Promises ao método
Porém a diferença é que teremos a resposta apenas da Promise mais rápida, ou seja, a primeira que apresentar um retorno
Se aplicarmos no mesmo exemplo sabemos que o retorno do método nunca será a primeira, pois ela demora mais que as outras
Veja então o race em ação:
const p4 = new Promise((resolve, reject) => { setTimeout(() => { resolve('Resolveu o timeout') }, 2000) }) const p5 = new Promise((resolve, reject) => { resolve('Promessa 5 resolvida!') }) const p6 = new Promise((resolve, reject) => { resolve('Promessa 6 resolvida!') }) const resolveAllRace = Promise.race([p1, p2, p3]).then((data) => { console.log(data) // A resposta da mais rápida, que é a 5 })
Aqui a resposta do race é a Promise 5, isso porque o código da 5 e 6 são quase idênticos
Dada a ordem de execução ser 5 e depois 6, temos o retorno dela
Antes até mesmo do método all anterior, que responde depois
Isso por que o código de uma Promise é assíncrono, ou seja, executa em paralelo em nosso sistema
Exemplo real de Promise
Até agora foram criados exemplos que não são úteis no mundo real, apenas para entender como cada um dos recursos funciona
Então que aplicabilidade tem uma Promise em um projeto?
Como dito anteriormente a Fetch API retorna uma Promise, então podemos utilizar o nosso conhecimento adquirido para requisições externas
Veja um exemplo:
const userName = 'matheusbattisti' fetch(`https://api.github.com/users/${userName}`, { method: 'GET', headers: { Accept: 'application/vnd.github.v3+json', }, }) .then((response) => { return response.json() }) .then((data) => { console.log(`O nome do usuário é: ${data.name}`) // O nome do usuário é: Matheus }) .catch((error) => { console.log(`Houve algum erro: ${error}`) })
Aqui mandamos um request de GET para a API do GitHub em busca de um usuário
Como dito antes, o fetch retorna uma Promise
Então podemos dar continuidade com then e catch
Aqui realizamos uma transformação de dados de texto para JSON, com o método json()
E depois retornamos o nome do usuário, no último then
Se algum erro algum ocorrer há o bloco com o método catch
Este exemplo é muito utilizado nas aplicações de hoje em dia, com frameworks React e Vue.js
Conclusão
Neste artigo você aprendeu a como utilizar Promises em JavaScript, um recurso moderno e muito simples
Vimos sua inicialização e também diversos métodos que compõe o recurso de promessas
- new Promise: cria uma nova promessa;
- resolve: resolve uma promessa, entregando uma mensagem de sucesso;
- reject: rejeita uma promessa, entregando uma mensagem de erro;
- then: encadeamento de Promises;
- catch: tratamento de erro das promessas;
- race: executa diversas promessas ao mesmo tempo, retornando a resposta da mais rápida;
- all: executa diversas promessas, retornando a resposta de todas elas;
Confira nossos cursos gratuitos no Youtube, com vídeos todos os dias!
Se inscreva e ative o sininho para receber as notificações e aprender mais ainda sobre desenvolvimento web!
Veja também nosso catálogo de cursos na Udemy, todos com exercícios e projetos práticos, nas mais diversas tecnologias
O link acima contém um cupom de desconto para os cursos!