Последовательность отправки AJAX

116
25 января 2021, 20:50

Есть задача: С элементов страницы собираются данные (ID). Далее их, по очереди, надо отправить на сервер, но чётко последовательно(после завершения-следующий). Один запрос - один ID. Все мои решения в результате "кладёт" сервер, так как за раз уходят сотни запросов. Если ставить async - всё висит до завершения. Если городить задержку по коду (функция Sleep для примера в коде) то запросы уходят с заданными задержками, то опять всё висит до завершения всех оправок. Если использовать методы setInerval или setTimeout - тоже нифига не работает, всегда уходит тупо пачкой. Возможно я эти методы не грамотно использую.
Суть вопроса - как описать эти три функции, что бы при запуске перовй функции(countItems_checkbox()), запросы уходили по очереди, каждый запрос дожидался ответа, и после пошёл следующий?

    function countItems_checkbox()
    {
    $(".form-group label[for='supplier_categories']").next().children().each(function(){
        obj = $(this).find('label');
        cat_id = $(this).find('input').val();
        getCountItemsValue(cat_id, obj);
    });
    }
    function getCountItemsValue(cat_id, obj)
    {
        sendAjax(cat_id, obj);
    }
    function sendAjax(cat_id, obj) {
        $.ajax({
            type: 'POST',
            url: '/modules/suppliermapper/ajax.php',
            dataType: 'json',
            async: true,
            data: {
                cat_id: cat_id,
                suppliermapper_id: $('#suppliermapper_id').val(),
                get_count_items: 1 },
            success: function(data) {
                var textArray = obj.context.innerText.split("|");
                var text = textArray[0].trim();
                var input = obj.context.firstElementChild.firstElementChild.outerHTML;
                var id = obj.context.firstElementChild.htmlFor;
                obj.context.firstElementChild.innerHTML = input+text+' | ('+data+')';
            },
            error:  function(xhr, str){
                $('#mapping_result').html('Возникла ошибка обновления данных(getCountItemsValue): ' + xhr.responseCode).css('color','red');
            }
        })
    }
    function sleep(milliseconds) {
       var start = new Date().getTime();
       for (var i = 0; i < 1e7; i++) {
        if ((new Date().getTime() - start) > milliseconds){
            break;
        }
      }
    }
Answer 1

Можно собрать цепочку промисов:

function countItems_checkbox()
{
  let p = Promise.resolve();
  $(".form-group label[for='supplier_categories']").next().children().each(function(){
    obj = $(this).find('label');
    cat_id = $(this).find('input').val();
    p = p.then(() => getCountItemsValue(cat_id, obj));
  });
}

Функция getCountItemsValue и другие также должны возвращать промисы.
И начать стоит с sendAjax:

function sendAjax() {
  return new Promise(resolve, reject) {
    $.ajax({... success() { ... resolve();}})
  }
}

Я бы также рекомендовал рассмотреть переход на нативный Fetch API, в котором промисы есть из коробки.

READ ALSO
Вопрос о курсоре (mac os но возможно и web и windows)

Вопрос о курсоре (mac os но возможно и web и windows)

Проблема в том что есть сайт на котором спрятан курсор в принципе ( cursor: none ) но когда на мой mac приходит уведомление с другого приложения например...

126
Как лучше из объекта получить массив его keys , у которых свойство = true?

Как лучше из объекта получить массив его keys , у которых свойство = true?

Подскажите как заменить на более es6, чтобы обойтись без let и push

118
Cannot read property &#39;setState&#39; of undefined [дубликат]

Cannot read property 'setState' of undefined [дубликат]

при изменении импута какого либо, возникает ошибка - Cannot read property 'setState' of undefined

142
Как запретить менеджеру паролей в Chrome влиять на шрифт в инпуте?

Как запретить менеджеру паролей в Chrome влиять на шрифт в инпуте?

Менеджер паролей изменяет шрифт, когда наводишь на какой-нибудь айтемКак можно этого избежать? Сталкивался кто? Два скриншота прилагаю

97