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:
Top comments (0)