Conceitos Básicos
O que é Programação Assíncrona?
Programação assíncrona é uma técnica de programação que permite a execução de operações que podem demorar um certo tempo para serem concluídas, como requisições de rede, leitura de arquivos ou consultas a bancos de dados, sem bloquear o fluxo principal do programa. Em vez de esperar que essas operações terminem, o programa pode continuar executando outras tarefas. Isso é especialmente útil em aplicações web, onde a responsividade e a performance são cruciais para a experiência do usuário.
Callbacks e Promises
Antes do advento de async/await, a programação assíncrona em JavaScript era tradicionalmente feita usando callbacks e Promises.
Callbacks: Um callback é uma função passada como argumento para outra função, que será executada após a conclusão de uma operação assíncrona. No entanto, callbacks podem levar ao que é conhecido como “callback hell”, onde múltiplos callbacks aninhados tornam o código difícil de ler e manter.
function fetchData(callback) { setTimeout(() => { callback('data'); }, 1000); } fetchData((data) => { console.log(data); });
Promises: Promises foram introduzidas para melhorar a legibilidade do código assíncrono. Uma Promise representa um valor que pode estar disponível agora, no futuro ou nunca. Promises permitem encadear operações assíncronas de maneira mais clara e gerenciável.
function fetchData() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('data'); }, 1000); }); } fetchData().then((data) => { console.log(data); }).catch((error) => { console.error(error); });
O que é Async/Await?
async
e await
são palavras-chave introduzidas no ES2017 (ES8) que simplificam ainda mais o uso de Promises, permitindo escrever código assíncrono que parece síncrono.
async: A palavra-chave
async
é usada para declarar uma função assíncrona. Uma função assíncrona sempre retorna uma Promise.async function fetchData() { return 'data'; } fetchData().then((data) => { console.log(data); });
await: A palavra-chave
await
só pode ser usada dentro de uma função assíncrona. Ela pausa a execução da função até que a Promise seja resolvida, simplificando o fluxo do código.async function fetchData() { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data; } fetchData().then((data) => { console.log(data); });
Com async
e await
, o código assíncrono se torna mais linear e fácil de entender, eliminando a necessidade de encadeamento excessivo de then
e catch
.
Exemplos Práticos e Tratamento de Erros
Exemplo Simples
Vamos começar com um exemplo simples de uma função assíncrona que busca dados de uma API usando async/await
.
async function fetchData() { const response = await fetch('https://api.example.com/data'); const data = await response.json(); return data;
} fetchData().then(data => { console.log(data);
});
Múltiplas Chamadas Assíncronas
Às vezes, você precisa fazer múltiplas chamadas assíncronas e esperar que todas sejam concluídas. Você pode usar Promise.all
para isso.
async function fetchMultipleData() { const [response1, response2] = await Promise.all([ fetch('https://api.example.com/data1'), fetch('https://api.example.com/data2') ]); const data1 = await response1.json(); const data2 = await response2.json(); return { data1, data2 };
} fetchMultipleData().then(({ data1, data2 }) => { console.log(data1, data2);
});
Tratamento de Erros com Try/Catch
O uso de try/catch
em funções assíncronas permite capturar e lidar com erros de forma clara e concisa.
async function fetchData() { try { const response = await fetch('https://api.example.com/data'); if (!response.ok) { throw new Error('Network response was not ok'); } const data = await response.json(); return data; } catch (error) { console.error('Failed to fetch data:', error); }
} fetchData().then(data => { if (data) { console.log(data); }
});
Exemplo Completo: Integração com API e Tratamento de Erros
Vamos combinar tudo o que aprendemos em um exemplo mais completo. Suponha que estamos construindo uma função que busca e processa dados de múltiplas APIs e lida com possíveis erros.
async function fetchUserData() { try { const userResponse = await fetch('https://api.example.com/user'); if (!userResponse.ok) { throw new Error('Failed to fetch user data'); } const userData = await userResponse.json(); const postsResponse = await fetch(`https://api.example.com/users/${userData.id}/posts`); if (!postsResponse.ok) { throw new Error('Failed to fetch user posts'); } const userPosts = await postsResponse.json(); return { userData, userPosts }; } catch (error) { console.error('Error fetching data:', error); }
} fetchUserData().then(data => { if (data) { console.log('User Data:', data.userData); console.log('User Posts:', data.userPosts); }
});
Conclusão
async/await
simplifica significativamente a programação assíncrona em JavaScript, tornando o código mais legível e fácil de manter. Com a capacidade de escrever código assíncrono que parece síncrono, desenvolvedores podem evitar os problemas comuns de callbacks aninhados e o encadeamento excessivo de Promises.
Recursos Adicionais
Para aprofundar seu conhecimento sobre async/await
e programação assíncrona, aqui estão alguns recursos úteis:
Discover more from Coursity
Subscribe to get the latest posts sent to your email.