Promises, APIs, Web APIs e Programação Assíncrona
🚀 Objetivo: Dominar programação assíncrona e integração com APIs modernas
0% concluído
Promises, async/await e Timers
Promises são como "promessas" no JavaScript. Elas representam algo que vai acontecer no futuro - pode dar certo (resolve) ou dar errado (reject)!
// Criando uma Promise simples
function fazerPedido(item) {
return new Promise((resolve, reject) => {
console.log(`🍕 Fazendo pedido de ${item}...`);
// Simular tempo de preparo (2 segundos)
setTimeout(() => {
const sucesso = Math.random() > 0.3; // 70% de chance de sucesso
if (sucesso) {
resolve(`✅ ${item} está pronto!`);
} else {
reject(`❌ Ops! Não conseguimos fazer ${item}`);
}
}, 2000);
});
}
// Usando a Promise
fazerPedido('Pizza Margherita')
.then(resultado => {
console.log(resultado); // Se deu certo
})
.catch(erro => {
console.log(erro); // Se deu errado
})
.finally(() => {
console.log('🏁 Pedido finalizado!');
});
Async/await é uma forma mais limpa e fácil de trabalhar com Promises. É como escrever código assíncrono de forma síncrona!
// Função para simular download
function baixarArquivo(nome, tamanho) {
return new Promise((resolve) => {
console.log(`📥 Iniciando download de ${nome}...`);
// Simular progresso do download
let progresso = 0;
const intervalo = setInterval(() => {
progresso += 20;
console.log(`📊 ${nome}: ${progresso}%`);
if (progresso >= 100) {
clearInterval(intervalo);
resolve(`✅ ${nome} baixado com sucesso!`);
}
}, 500);
});
}
// Usando async/await
async function gerenciarDownloads() {
try {
console.log('🚀 Iniciando downloads...');
// Aguardar primeiro download
const arquivo1 = await baixarArquivo('documento.pdf', '2MB');
console.log(arquivo1);
// Aguardar segundo download
const arquivo2 = await baixarArquivo('imagem.jpg', '5MB');
console.log(arquivo2);
console.log('🎉 Todos os downloads concluídos!');
} catch (error) {
console.log('❌ Erro no download:', error);
}
}
// Executar
gerenciarDownloads();
Crie uma função que simula um cronômetro usando async/await:
Tarefa: Complete a função do cronômetro usando async/await.
Fetch API, JSON e Web Storage
A Fetch API permite buscar dados de serviços externos. É como pedir informações para outros sites ou serviços na internet!
// Buscando dados de uma API pública
async function buscarCEP(cep) {
try {
console.log(`🔍 Buscando informações do CEP: ${cep}`);
// Fazer requisição para API dos Correios
const response = await fetch(`https://viacep.com.br/ws/${cep}/json/`);
// Verificar se a requisição foi bem-sucedida
if (!response.ok) {
throw new Error('CEP não encontrado');
}
// Converter resposta para JSON
const dados = await response.json();
// Verificar se o CEP é válido
if (dados.erro) {
throw new Error('CEP inválido');
}
console.log('✅ Dados encontrados:', dados);
return dados;
} catch (error) {
console.log('❌ Erro:', error.message);
throw error;
}
}
// Função para exibir os dados
async function consultarCEP() {
const cep = '01310-100'; // CEP da Av. Paulista
try {
const endereco = await buscarCEP(cep);
console.log(`📍 Endereço: ${endereco.logradouro}`);
console.log(`🏙️ Cidade: ${endereco.localidade}`);
console.log(`🗺️ Estado: ${endereco.uf}`);
} catch (error) {
console.log('Não foi possível consultar o CEP');
}
}
// Executar consulta
consultarCEP();
JSON é um formato para trocar dados, e Web Storage permite salvar informações no navegador do usuário!
// Sistema de favoritos usando localStorage
class GerenciadorFavoritos {
constructor() {
this.chave = 'meus-favoritos';
}
// Carregar favoritos do localStorage
carregarFavoritos() {
try {
const dados = localStorage.getItem(this.chave);
return dados ? JSON.parse(dados) : [];
} catch (error) {
console.log('Erro ao carregar favoritos:', error);
return [];
}
}
// Salvar favoritos no localStorage
salvarFavoritos(favoritos) {
try {
localStorage.setItem(this.chave, JSON.stringify(favoritos));
console.log('✅ Favoritos salvos!');
} catch (error) {
console.log('❌ Erro ao salvar:', error);
}
}
// Adicionar item aos favoritos
adicionarFavorito(item) {
const favoritos = this.carregarFavoritos();
// Verificar se já existe
if (!favoritos.find(fav => fav.id === item.id)) {
favoritos.push({
id: item.id,
nome: item.nome,
categoria: item.categoria,
adicionadoEm: new Date().toISOString()
});
this.salvarFavoritos(favoritos);
console.log(`⭐ ${item.nome} adicionado aos favoritos!`);
return true;
} else {
console.log(`ℹ️ ${item.nome} já está nos favoritos`);
return false;
}
}
// Remover item dos favoritos
removerFavorito(id) {
const favoritos = this.carregarFavoritos();
const novosFavoritos = favoritos.filter(fav => fav.id !== id);
this.salvarFavoritos(novosFavoritos);
console.log('🗑️ Item removido dos favoritos');
}
// Listar todos os favoritos
listarFavoritos() {
const favoritos = this.carregarFavoritos();
console.log('📋 Seus favoritos:', favoritos);
return favoritos;
}
}
// Usando o gerenciador
const favoritos = new GerenciadorFavoritos();
// Adicionar alguns itens
favoritos.adicionarFavorito({
id: 1,
nome: 'JavaScript',
categoria: 'Linguagem'
});
favoritos.adicionarFavorito({
id: 2,
nome: 'React',
categoria: 'Framework'
});
// Listar favoritos
favoritos.listarFavoritos();
Crie uma função que busca informações de usuários do GitHub usando a API pública:
Tarefa: Complete a função para buscar dados do GitHub.
Web APIs e Service Workers
A Geolocation API permite acessar a localização do usuário (com permissão). É útil para apps que precisam saber onde o usuário está!
// Função para obter localização do usuário
async function obterLocalizacao() {
return new Promise((resolve, reject) => {
// Verificar se o navegador suporta geolocalização
if (!navigator.geolocation) {
reject(new Error('Geolocalização não suportada'));
return;
}
console.log('📍 Solicitando permissão de localização...');
// Opções para a geolocalização
const opcoes = {
enableHighAccuracy: true, // Alta precisão
timeout: 10000, // Timeout de 10 segundos
maximumAge: 60000 // Cache por 1 minuto
};
navigator.geolocation.getCurrentPosition(
(posicao) => {
const { latitude, longitude, accuracy } = posicao.coords;
console.log('✅ Localização obtida!');
console.log(`📍 Latitude: ${latitude}`);
console.log(`📍 Longitude: ${longitude}`);
console.log(`🎯 Precisão: ${accuracy} metros`);
resolve({
latitude,
longitude,
accuracy,
timestamp: posicao.timestamp
});
},
(erro) => {
console.log('❌ Erro ao obter localização:', erro.message);
reject(erro);
},
opcoes
);
});
}
// Função para buscar informações sobre a localização
async function obterInfoLocalizacao(lat, lng) {
try {
// Usar API de geocodificação reversa (exemplo com OpenStreetMap)
const url = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}`;
const response = await fetch(url);
const dados = await response.json();
return {
endereco: dados.display_name,
cidade: dados.address?.city || dados.address?.town,
estado: dados.address?.state,
pais: dados.address?.country
};
} catch (error) {
console.log('Erro ao buscar informações:', error);
return null;
}
}
// Função principal
async function mostrarLocalizacao() {
try {
const localizacao = await obterLocalizacao();
const info = await obterInfoLocalizacao(
localizacao.latitude,
localizacao.longitude
);
if (info) {
console.log('🏙️ Você está em:', info.cidade);
console.log('🗺️ Estado:', info.estado);
console.log('🌍 País:', info.pais);
}
} catch (error) {
console.log('Não foi possível obter sua localização');
}
}
// Executar
mostrarLocalizacao();
A Notification API permite enviar notificações para o usuário, mesmo quando ele não está olhando para a página!
// Sistema de notificações
class GerenciadorNotificacoes {
constructor() {
this.permissao = Notification.permission;
}
// Solicitar permissão para notificações
async solicitarPermissao() {
if (!('Notification' in window)) {
throw new Error('Notificações não suportadas');
}
if (this.permissao === 'granted') {
console.log('✅ Permissão já concedida!');
return true;
}
console.log('🔔 Solicitando permissão...');
const resultado = await Notification.requestPermission();
this.permissao = resultado;
if (resultado === 'granted') {
console.log('✅ Permissão concedida!');
return true;
} else {
console.log('❌ Permissão negada');
return false;
}
}
// Enviar notificação simples
enviarNotificacao(titulo, opcoes = {}) {
if (this.permissao !== 'granted') {
console.log('❌ Sem permissão para notificações');
return;
}
const configuracao = {
body: opcoes.mensagem || 'Nova notificação!',
icon: opcoes.icone || '🔔',
badge: '🔔',
tag: opcoes.tag || 'notificacao-geral',
requireInteraction: opcoes.persistente || false,
...opcoes
};
const notificacao = new Notification(titulo, configuracao);
// Eventos da notificação
notificacao.onclick = () => {
console.log('👆 Notificação clicada!');
window.focus();
notificacao.close();
};
notificacao.onshow = () => {
console.log('👁️ Notificação exibida');
};
notificacao.onclose = () => {
console.log('❌ Notificação fechada');
};
// Fechar automaticamente após 5 segundos
if (!configuracao.requireInteraction) {
setTimeout(() => {
notificacao.close();
}, 5000);
}
return notificacao;
}
// Notificação com progresso
notificarProgresso(titulo, progresso) {
this.enviarNotificacao(titulo, {
mensagem: `Progresso: ${progresso}%`,
tag: 'progresso',
icon: '📊'
});
}
// Notificação de lembrete
agendarLembrete(titulo, mensagem, segundos) {
console.log(`⏰ Lembrete agendado para ${segundos} segundos`);
setTimeout(() => {
this.enviarNotificacao(titulo, {
mensagem: mensagem,
tag: 'lembrete',
icon: '⏰',
persistente: true
});
}, segundos * 1000);
}
}
// Usando o gerenciador
const notificacoes = new GerenciadorNotificacoes();
// Exemplo de uso
async function testarNotificacoes() {
const permissao = await notificacoes.solicitarPermissao();
if (permissao) {
notificacoes.enviarNotificacao('Olá!', {
mensagem: 'Sistema de notificações funcionando!'
});
// Agendar lembrete
notificacoes.agendarLembrete(
'Lembrete',
'Não esqueça de praticar JavaScript!',
10
);
}
}
// Executar teste
testarNotificacoes();
Teste conceitos de programação assíncrona!
// Saída aparecerá aqui...
Teste seus conhecimentos assíncronos!
Crie um sistema que monitora múltiplas APIs e exibe o status de cada uma.
Simule um sistema de upload de arquivos com progresso e notificações.