@dc65k

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

Всем привет, есть задача со следующими условиями:
1. Написать функцию, получающую на вход массив ссылок и число, указывающее максимальное количество одновременных запросов.
2. Одновременно должно выполняться не более указанного числа запросов.
3. Должен возвращаться массив результатов в той же последовательности, что и адреса запросов.
4. Нельзя делать повторные запросы на дублирующиеся адреса (при этом результат всё равно должен присутствовать в результирующем массиве).
makeRequest([
    'url1',
    'url2',
    'url1',
    'url3'
], 2).then(([
	    result1,
	    result2,
	    result1,
	    result3
	]) => {
});

Итак, моё решение:
const removingDuplicates = (arr) => {
    return arr.filter((item, i, arr) => arr.indexOf(item) === i)
}

function makeRequests (urls, maxNumberRequests) {
    const uniqueUrls = removingDuplicates(urls);
    // console.log(uniqueUrls);

    let response = null;

    uniqueUrls.forEach(async (url, idx) => {
        // console.log('url', url, idx);

        if (idx === maxNumberRequests) {
            return false;
        }

        response = await fetch(url, {
            method: 'POST',
            body: "statistics",
            keepalive: true
        });

        return response;
    });
}

makeRequests([
    'url1',
    'url2',
    'url1',
    'url3'
], 2);

Собственно, подскажите, что мне нужно подправить, полагаю, что я не совсем правильно понял условие задачи.
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
0xD34F
@0xD34F Куратор тега JavaScript
подскажите, что мне нужно подправить

всё нужно подправить

function makeRequests(urls, max) {
  return new Promise(resolve => {
    const results = Array(urls.length).fill(null);
    const groupedUrls = urls.reduce((acc, n, i) => ((acc[n] ||= []).push(i), acc), {});
    const uniqueUrls = Object.keys(groupedUrls);
    let countRequests = 0;
    let countResponses = 0;

    for (let i = 0; i < Math.min(max, uniqueUrls.length); i++) {
      request();
    }

    function request() {
      const url = uniqueUrls[countRequests++];
      fetch(url)
        .then(result => result.json())
        .catch(error => error)
        .then(result => {
          groupedUrls[url].forEach(n => results[n] = result);

          if (++countResponses === uniqueUrls.length) {
            resolve(results);
          } else if (countRequests < uniqueUrls.length) {
            request();
          }
        });
    }
  });
}

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
firedragon
@firedragon
Senior .NET developer
Вас не смущает что яваскрипт однопоточный? Так что одновременно никак, но ! Он и событийный а события в нашем мире имеют разную длительность. Поэтому по факту вы должны обернуть каждый запрос в promise и ждать выполнения всех, позже отсортировать результат или отобразить ошибку или отобразить только валидные данные
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Artezio Нижний Новгород
от 130 000 до 180 000 ₽
Artezio Москва
от 160 000 до 220 000 ₽
Intspirit Краснодар
от 80 000 до 150 000 ₽
25 янв. 2021, в 11:26
3000 руб./за проект
21 янв. 2021, в 20:39
60000 руб./за проект
25 янв. 2021, в 11:12
2000 руб./за проект