Gernar
HTTP, API и сеть

Как выполнить два запроса параллельно

Разбор вопроса «Как выполнить два запроса параллельно» для Frontend Developer: что проверяет интервьюер, ключевые тезисы, практические примеры и частые ошибки.

Вопрос

Как выполнить два запроса параллельно

Профессия

Frontend Developer

Что хочет услышать интервьюер

Интервьюер хочет убедиться, что кандидат понимает асинхронное выполнение операций и умеет эффективно работать с несколькими запросами. Важно показать знание современных API (Promise.all) и обработки ошибок.

Ключевые тезисы

  • Использовать Promise.all() для параллельного выполнения запросов и ожидания их завершения
  • Пример: Promise.all([fetch(url1), fetch(url2)]) вернет массив результатов
  • Обработка ошибок: если один запрос завершится с ошибкой, весь Promise.all() отклонится (можно использовать Promise.allSettled() для независимой обработки)

Подробный ответ

В JavaScript выполнение двух или более запросов параллельно можно организовать с помощью Promise.all(). Этот метод принимает массив промисов и возвращает новый промис, который выполнится только тогда, когда все переданные промисы завершатся успешно. Если хотя бы один из промисов завершится с ошибкой, весь Promise.all() также завершится с ошибкой. Это полезно, когда вам нужно дождаться завершения нескольких асинхронных операций перед выполнением дальнейших действий. Для обработки ошибок можно использовать блок try/catch или метод .catch() на промисах. Если важно получить результаты всех запросов независимо от их успешности, можно использовать Promise.allSettled(), который возвращает массив объектов с результатами каждого промиса, включая ошибки. Promise.allSettled() полезен, когда нужно обработать все результаты, даже если некоторые запросы завершились неудачно. Также стоит отметить, что async/await можно использовать совместно с Promise.all(), что делает код более читаемым и удобным для работы с асинхронными операциями.

Практические примеры

Пример 1

Пример использования Promise.all():

const fetchData = async () => {
  try {
    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();
    console.log(data1, data2);
  } catch (error) {
    console.error('Ошибка при выполнении запросов:', error);
  }
};

fetchData();

Пример 2

Пример использования Promise.allSettled():

const fetchData = async () => {
  const results = await Promise.allSettled([
    fetch('https://api.example.com/data1'),
    fetch('https://api.example.com/data2')
  ]);
  results.forEach((result) => {
    if (result.status === 'fulfilled') {
      console.log('Успешный запрос:', result.value);
    } else {
      console.error('Ошибка запроса:', result.reason);
    }
  });
};

fetchData();

Частые ошибки

  • Типичная ошибка — неправильная обработка ошибок в Promise.all(). Если хотя бы один запрос завершится с ошибкой, весь Promise.all() завершится с ошибкой, и разработчики часто забывают обработать эту ситуацию.
  • Еще одна ошибка — использование Promise.all() для выполнения большого количества запросов одновременно, что может привести к перегрузке сервера или превышению лимитов на количество одновременных запросов.

Связанные темы

  • Асинхронное программирование в JavaScript
  • Работа с промисами и async/await
  • Методы работы с несколькими промисами (Promise.race, Promise.any)
  • Оптимизация производительности при выполнении множества запросов

Follow-up вопросы

Как обработать ошибки в Promise.all()?

Уровень: basic

Если один из промисов в Promise.all() завершится с ошибкой, весь Promise.all() будет отклонен. Для обработки ошибок можно использовать блок try/catch или метод catch() на самом Promise.all().

Чем отличается Promise.all() от Promise.allSettled()?

Уровень: intermediate

Promise.all() завершается с ошибкой, если хотя бы один промис отклонен, а Promise.allSettled() возвращает массив результатов всех промисов независимо от их состояния (выполнен или отклонен).

Можно ли использовать async/await с Promise.all()?

Уровень: basic

Да, можно использовать async/await с Promise.all(). Например: const [result1, result2] = await Promise.all([fetch(url1), fetch(url2)]). Это позволяет упростить код и сделать его более читаемым.

Как ограничить количество параллельных запросов?

Уровень: advanced

Для ограничения количества параллельных запросов можно использовать библиотеки, например, p-limit, или реализовать очередь с помощью массива и цикла, где промисы добавляются и выполняются по очереди.

Как обработать результаты запросов, если они приходят в разное время?

Уровень: intermediate

Для обработки результатов, приходящих в разное время, можно использовать Promise.race(), который завершится, когда первый промис выполнится, или обрабатывать результаты по мере их поступления через then() или async/await.

Содержание