26 de setembro de 2024 • 6 min de leitura
Melhore o Desempenho com Chamadas de API Simultâneas usando Promise.all
Realize múltiplas chamadas de API de forma concorrente para otimizar o desempenho da sua aplicação!
Quando trabalhamos com aplicações que fazem várias requisições a APIs, é comum realizar essas chamadas de forma sequencial, o que pode impactar negativamente o desempenho. Neste artigo, vamos explorar como fazer múltiplas chamadas de API simultaneamente usando Promise.all
, melhorando significativamente o tempo de resposta.
O Jeito Ruim: Chamadas Sequenciais
No exemplo abaixo, as chamadas de API são feitas uma após a outra, esperando a resposta de cada uma antes de prosseguir para a próxima:
async function fetchData() {
const userResponse = await fetch('/api/user');
const userData = await userResponse.json();
const productsResponse = await fetch('/api/products');
const productsData = await productsResponse.json();
const ordersResponse = await fetch('/api/orders');
const ordersData = await ordersResponse.json();
// Utilize os dados aqui
}
Problema: Cada chamada de API aguarda a conclusão da anterior, aumentando o tempo total de execução proporcionalmente ao número de chamadas.
O Jeito Recomendado: Chamadas Concorrentes com Promise.all
Utilizando Promise.all
, podemos iniciar todas as chamadas de API ao mesmo tempo e esperar que todas sejam concluídas:
async function fetchData() {
const [userResponse, productsResponse, ordersResponse] = await Promise.all([
fetch('/api/user'),
fetch('/api/products'),
fetch('/api/orders')
]);
const [userData, productsData, ordersData] = await Promise.all([
userResponse.json(),
productsResponse.json(),
ordersResponse.json()
]);
// Utilize os dados aqui
}
Vantagem: As chamadas de API são iniciadas simultaneamente, reduzindo significativamente o tempo total de espera.
Explicação Detalhada
Chamadas Sequenciais vs. Concorrentes
- Sequenciais: A próxima chamada só é iniciada após a conclusão da anterior.
- Concorrentes: Todas as chamadas são iniciadas quase ao mesmo tempo, sem esperar pelas anteriores.
Por Que Promise.all
é Eficiente?
- Execução Simultânea: Inicia todas as promessas ao mesmo tempo.
- Sincronização: Aguarda que todas sejam resolvidas ou que uma seja rejeitada.
- Melhor Desempenho: Reduz o tempo total de espera ao máximo tempo individual de uma chamada, em vez da soma dos tempos.
Outro Método: Iniciando Chamadas Sem Promise.all
Também podemos iniciar as chamadas sem esperar, armazenando as promessas e aguardando sua resolução posteriormente:
async function fetchData() {
const userPromise = fetch('/api/user');
const productsPromise = fetch('/api/products');
const ordersPromise = fetch('/api/orders');
const userResponse = await userPromise;
const productsResponse = await productsPromise;
const ordersResponse = await ordersPromise;
const userData = await userResponse.json();
const productsData = await productsResponse.json();
const ordersData = await ordersResponse.json();
// Utilize os dados aqui
}
Observação: Embora funcione, o uso de Promise.all
torna o código mais limpo e fácil de entender.
Lidando com Erros: Promise.all
vs. Promise.allSettled
Comportamento do Promise.all
Se alguma das promessas for rejeitada, o Promise.all
rejeita imediatamente com o erro da promessa que falhou:
async function fetchData() {
try {
const responses = await Promise.all([
fetch('/api/user'),
fetch('/api/products'),
fetch('/api/orders')
]);
// Processamento dos dados...
} catch (error) {
console.error('Uma das chamadas de API falhou:', error);
}
}
Quando usar: Quando a falha de uma chamada invalida todo o conjunto de dados que você precisa.
Usando Promise.allSettled
para Mais Resiliência
Se você precisa que todas as chamadas sejam concluídas, mesmo que algumas falhem, use Promise.allSettled
:
async function fetchData() {
const results = await Promise.allSettled([
fetch('/api/user'),
fetch('/api/products'),
fetch('/api/orders')
]);
results.forEach((result) => {
if (result.status === 'fulfilled') {
// result.value contém a resposta bem-sucedida
} else {
// result.reason contém o erro
console.error('Erro na chamada de API:', result.reason);
}
});
// Utilize os dados disponíveis
}
Vantagens:
- Robustez: Continua executando mesmo se algumas promessas forem rejeitadas.
- Feedback Completo: Fornece o status de cada promessa, permitindo tratamento individual.
Comparação de Abordagens
Método | Quando Usar |
---|---|
Chamadas Sequenciais | Quando as chamadas dependem umas das outras. |
Promise.all | Quando todas as chamadas são independentes e a falha de uma invalida o resultado. |
Promise.allSettled | Quando deseja obter o máximo de dados possível, mesmo se algumas chamadas falharem. |
Exemplo Prático Completo
Código Sequencial (Ineficiente)
async function getData() {
const user = await fetchUser();
const profile = await fetchUserProfile(user.id);
const posts = await fetchUserPosts(user.id);
return { user, profile, posts };
}
Código Concorrente com Promise.all
(Eficiente)
async function getData() {
const userPromise = fetchUser();
const [user, profile, posts] = await Promise.all([
userPromise,
userPromise.then(user => fetchUserProfile(user.id)),
userPromise.then(user => fetchUserPosts(user.id))
]);
return { user, profile, posts };
}
Nota: Neste exemplo, usamos o resultado de userPromise
para iniciar as outras chamadas, mantendo a execução concorrente onde possível.
Conclusão
Utilizar chamadas de API simultâneas pode melhorar significativamente o desempenho da sua aplicação. Ao optar por Promise.all
ou Promise.allSettled
, você tem controle sobre como lidar com possíveis falhas e pode otimizar a experiência do usuário.
Dicas Finais:
- Analise as Dependências: Certifique-se de que as chamadas não dependem umas das outras antes de executá-las simultaneamente.
- Gerencie Erros Adequadamente: Escolha entre
Promise.all
ePromise.allSettled
com base em como você deseja lidar com erros. - Mantenha o Código Legível: Prefira abordagens que tornem o código mais claro e fácil de manter.
Referências:
Esperamos que este artigo ajude você a melhorar o desempenho das suas aplicações JavaScript ao lidar com múltiplas chamadas de API!