Как выполнить все асинхронные запросы параллельно в Node.js?

«Как выполнить все асинхронные запросы параллельно в Node.js?» — вопрос из категории Асинхронность, который задают на 26% собеседований Node.js Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Node.js для параллельного выполнения независимых асинхронных операций я использую Promise.all(). Это позволяет запустить все промисы одновременно и дождаться их завершения.

Базовый пример с HTTP-запросами:

const axios = require('axios');

async function fetchMultipleAPIs(urls) {
  const promises = urls.map(url => axios.get(url));

  try {
    const responses = await Promise.all(promises);
    return responses.map(res => res.data);
  } catch (error) {
    // Если один запрос падает, падает весь Promise.all
    console.error('One of the requests failed:', error);
    throw error;
  }
}

// Использование
const apiEndpoints = [
  'https://api.example.com/users',
  'https://api.example.com/posts',
  'https://api.example.com/comments'
];

const data = await fetchMultipleAPIs(apiEndpoints);
console.log('All data fetched:', data);

Когда нужна обработка ошибок без прерывания:

async function fetchWithSettled(urls) {
  const promises = urls.map(async (url) => {
    try {
      const response = await axios.get(url);
      return { status: 'fulfilled', value: response.data };
    } catch (error) {
      return { status: 'rejected', reason: error.message };
    }
  });

  return await Promise.all(promises);
}

// Или используем встроенный Promise.allSettled (Node.js 12.9.0+)
const results = await Promise.allSettled(promises);
const successful = results
  .filter(r => r.status === 'fulfilled')
  .map(r => r.value);

Важные моменты из моего опыта:

  • Promise.all() оптимален для I/O операций (запросы к БД, API, файлы)
  • Для CPU-intensive задач лучше использовать worker threads
  • Всегда ограничиваю количество параллельных запросов к внешним API (например, с помощью p-limit)
  • При работе с базой данных иногда эффективнее использовать один сложный запрос вместо нескольких параллельных