Выполнение параллельных запросов при обращение к API (AXIOS, JS)

251
30 июня 2022, 00:30

Разрабатываю приложение на JS и есть необходимость обращения к api для получения записей. Но Api накладывает ограничение на количество одновременно получаемых записей не более 100 шт. это происходит следующим образом.

/**
* Данная функция делит ids на массивы по 100 шт.(так как api может вернуть только 100 записей)
* вызывает другую функцию, которая выполняет запросы.
* ожидает выполнения запроса, собирает всё в общий массив и отправляет результат
*/
const prepareRequest = async (ids) => {
    let items = [];
    while (ids && ids.length>0) {
        let tmpIds = ids.splice(0,100); // делим по на массивы по 100 записей
        let itemsTmp = await itemsRequest(tmpIds); // ожидаем получения результата
        items = [...items, ...itemsTmp]; // склеиваем массивы  
    }
    return items; // возвращаем результат
}
/**
* делает запрос к api ждёт выполнения и отдаёт результат
*/
const itemsRequest(ids) => async (ids) => {
    const response await axios.get('path/to/api', {
                         'params': {'ids': ids}
                         });
    if(response.data && response.data.length > 0) {
        return response.data;
    }
}

Проблема заключается в том, что запросы выполняются последовательно, а не параллельно. Есть ли какой-то способ выполнить данные запросы (по 100 шт.) параллельно и при этом, чтобы функция prepareRequest возвращала полный массив данных, а не по 100 шт.

Answer 1

Дам несколько определений отсюда и вырезку отсюда

Асинхронность говорит о порядке исполнения кода. Если вызываемая функция не возвращает значение сразу, а отдаёт управление вызывающему коду с обещанием выдать значение позже, то эта функция асинхронная. При этом нет никаких предположений о том, как это значение будет считаться: параллельно или нет.

Параллельность говорит о том, что в машине физически происходит несколько процессов одновременно. При этом, с точки зрения кода программы это всё может выглядеть вполне синхронно. Например, если подряд вызываются две функции, то исполняющая среда может решить по каким-то признакам, что эти функции независимы, и выполнить их параллельно. С точки зрения программы этого заметно не будет.

JavaScript сам по себе однопоточный, что означает то, что только один блок кода может запускаться за раз. Так как движок JS выполняет наш код, обрабатывая строку за строкой, он использует один стек вызова, чтобы продолжать отслеживать код, который выполняется в соответствии с установленным порядком. Тоже самое, что и делает стек — структура данных, которая записывает строки выполняемых инструкций и выполняет их в стиле LIFO, то есть Last In First Out, что переводится как, “последний пришел — первый обслужен”.

Вам же для вашего случая достаточно чтоб не блокировался поток (единственный) использовать Promise.all вот пример использования с библиотекой axious

READ ALSO
Оператор JavaScript, похожий на SQL «NOT LIKE»

Оператор JavaScript, похожий на SQL «NOT LIKE»

Как записать not like в следующем условии? В данном условии приведен просто like

158
Некорректная работа js в FireFox

Некорректная работа js в FireFox

Есть скрипт, который подставляет номер дома из выпадающего списка в TextBox , из которого будет сохранен в БДПосле сохранения адреса, при заходе...

215
Как обособить значения строкового массива?

Как обособить значения строкового массива?

Есть строковый массив из 7 значенийПри вводе числа система выдаёт день недели

240
Хранение и восстановление PrivateKey

Хранение и восстановление PrivateKey

Задача: после генерации PrivateKey обеспечить его хранение и дальнейшее восстановление для подписания документов и проверки созданных с его...

162