Как эффективно обрабатывать несколько связанных запросов?

Здравствуйте! <br/> <br/> Поделитесь, пожалуйста, правильным подходом к решению следующей задачи: <br/> У нас есть сервис с двумя методами: один получает массив из 500 id определённых сущностей, а другой извлекает конкретную сущность по id. Как можно вывести последние 10 сущностей? <br/> <br/> Я попытался реализовать это <a href="https://stackblitz.com/edit/hacker-news-top-stories-pu5wzsl6?file=src%2Fapp%2Fapp.component.ts%3AL26" rel="nofollow">в таком формате</a>, но порядок вывода оказалась неправильным (возможно, проблема в гонке запросов). Мне также кажется, что реализованный способ не оптимален. Запускается много запросов, и пока не вижу других вариантов, поскольку у нас есть только указанные методы, которые не поддерживают фильтрацию для единовременного получения нужных данных.
  • 23 декабря 2024 г. 19:33
Ответы на вопрос 2
Ваша задача заключается в том, чтобы эффективно обработать несколько связанных запросов для получения последних 10 сущностей по их ID. Действительно, если делать множество запросов для каждой сущности по отдельности, это может привести к проблемам с производительностью и неправильному порядку вывода данных.

Вот подход, который поможет вам оптимизировать этот процесс:

### 1. Использование пакетной обработки

Если ваш сервис не поддерживает пакетные запросы, вы можете сначала получить массив из 500 ID, а затем сделать один запрос, который будет извлекать все 500 сущностей. После этого ваши данные будут уже загружены, и вы сможете отфильтровать последние 10 из них.

### 2. Упорядочивание запросов

Если вы все же будете делать отдельные запросы, вы можете отслеживать порядок завершения каждого запроса. Для этого можно использовать `Promise.all` для запуска параллельных запросов, а затем упорядочить результаты.

### Пример реализации

Вот пример кода с использованием `Promise.all`, который демонстрирует подход:

```javascript
async function fetchIdsAndEntities() {
    // Получаем массив из 500 ID
    const ids = await fetchIds(); // Предполагаем, что эта функция вернет массив из 500 id

    // Создаем массив промисов для извлечения сущностей
    const fetchPromises = ids.map(id => fetchEntityById(id));

    // Ожидаем завершения всех запросов
    const entities = await Promise.all(fetchPromises);

    // Упорядочиваем по времени добавления и возвращаем последние 10
    return entities.sort((a, b) => b.timestamp - a.timestamp).slice(0, 10);
}

async function fetchEntityById(id) {
    // Здесь ваш код для извлечения сущности по ID
    // Вернем полученную сущность, например:
    const response = await fetch(`https://example.com/api/entities/${id}`);
    return response.json();
}

async function fetchIds() {
    // Здесь ваш код для получения массива из 500 id
    const response = await fetch(`https://example.com/api/ids`);
    return response.json();
}
```

### Описание кода:

1. **fetchIds**: Функция, которая делает запрос для получения массива из 500 ID.
2. **fetchEntityById**: Функция, которая делает запрос для получения сущности по ID.
3. **Promise.all**: Используется для запуска всех запросов параллельно. Это улучшает производительность по сравнению с последовательным выполнением.
4. **Сортировка и обрезка**: После получения всех сущностей используем метод `sort` для упорядочивания и `slice` для получения последних 10.

### Заключение

Такой подход минимизирует количество запросов к серверу и позволяет обрабатывать результаты в нужном порядке. Если ваш сервис поддерживает пакетные запросы в будущем, это также может значительно упростить реализацию.
Я бы посоветовал добавить на бек эндпоинт, который принимает на вход массив id и возвращает список записей. 
Сортировать список можно например на клиенте по свойству time.
Похожие вопросы