Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Как реализовать задачу с одновременными запросами на сервер? (https://javascript.ru/forum/dom-window/83036-kak-realizovat-zadachu-s-odnovremennymi-zaprosami-na-server.html)

voraa 01.09.2021 12:39

Конечно можно считать, что в гуглах сидят программеры, которые от избытка денег и времени делают никому не нужные оптимизации.
Цитата:

Сообщение от Aetae
Конечно же никакого spread и destructuring.

Вроде утверждается, что это неплохо оптимизированно, касаемо массивов.

Aetae 01.09.2021 12:48

voraa, неплохо. Но всё равно в 100500 раз больше времени занимает, чем потенциальные расходы от дырок.)
По твоей же ссылке прямо пишут "the performance difference between accessing holey or packed arrays is usually too small to matter or even be measurable".

Alexandroppolus 01.09.2021 13:57

Цитата:

Сообщение от dc65k
const sendRequests = (requests, maxRequestsCount) => {

У такого подхода есть баг: если мы отправим 2 порции запросов, то они пойдут параллельно, т.е. будет в два раза больше запросов одновременно - у них ведь 2 независимые очереди.
Запилил исправленную версию, которая позволяет отправлять несколько порций. Причем, вторая порция может начать исполняться ещё до того, как завершится первая.
function createSendRequests(func, limit) {
    let reqCount = 0;
    const queue = [];
    return function (requests) {
        console.log('sendRequests for ', requests.join(','));
        if (!requests || !requests.length) {
            return Promise.resolve([]);
        }
        return new Promise((resolve) => {
            const responses = Array.from({length: requests.length});
            let curUrlInd = 0;
            let requestDone = 0;

            while (curUrlInd < requests.length && reqCount < limit) {
                makeRequest(curUrlInd);
            }

            let inQueue = curUrlInd < requests.length;
            if (inQueue) {
                queue.push(nextRequest);
            }

            function nextRequest() {
                makeRequest(curUrlInd);
                if (inQueue && curUrlInd === requests.length) {
                    inQueue = false;
                    queue.shift();
                }
            }

            function makeRequest(n) {
                reqCount++;
                curUrlInd++;
                const req = requests[n];
                console.log('request for ', req);
                func(req).then(data => {
                    console.log('response for ', req);
                    responses[n] = {
                        data
                    };
                }, (err) => {
                    responses[n] = {
                        error: err || 'error'
                    };
                }).finally (() => {
                    reqCount--;
                    if (queue.length) {
                        queue[0]();
                    }
                    requestDone++;
                    if (requestDone === requests.length) {
                        resolve(responses);
                    }
                });
            }
        });
    };
}

// ----- использование -------------------------------------

function myFetch(req) {
    return new Promise((res) => {
        setTimeout(res, 1000, 'response for ' + req);
    });
}

var sendRequests = createSendRequests(myFetch, 5);

sendRequests([
    'reqA',
    'reqB',
]).then((data) => {
    console.log('responses 1', data);
});

sendRequests([
    'req1',
    'req2',
    'req3',
    'req4',
    'req5',
    'req6',
    'req7',
]).then((data) => {
    console.log('responses 2', data);
});

sendRequests([
    'req8',
    'req9',
    'req10',
    'req11',
    'req12',
]).then((data) => {
    console.log('responses 3', data);
});


Часовой пояс GMT +3, время: 18:59.