JQuery. Вызов функции после цикла .each с вызовами ajax

Я часами искал в Интернете и знаю, что, вероятно, мне нужно что-то сделать с отложенными объектами, но я не могу это сделать.

Во-первых, вот мой код:

$('#uploadButton').on('click', function () {
    //some preparation stuff (deleted)
    var panels = boxesContainer.find('.panel');
    var ajaxes = [];

    $.each(panels, function (index, panel) {
        //more preparation + declaration of variables

        function getIdAndPrepareData() {
            $.when(
            $.ajax({
                type: 'POST',
                url: 'url',
                data: {
                    'title': name
                }
            }))
                .done(function (result, textStatus, jqXHR) {
                if (result.success) {
                    var id = result.id;
                } else {
                    getIdAndPrepareData();
                }

                console.log('Created Id: ' + id);

                $.each(panelForms, function (index, form) {
                    var filesInput = //again, prep and vars 

                    $.each($(filesInput)[0].files, function (index, file) {
                        var formData = new FormData();
                        formData.append('file', file);
                        //more stuff
                        ajaxes.push({
                            'formData': formData,
                            'file': file
                        });
                    });
                });

            }).fail(function () {
                getIdAndPrepareData();
            });
        }

        getIdAndPrepareData();

    });

    $.ajax().promise().done(function () {
        console.log('bla bla bla');
    });
});

Итак, в основном, я перебираю определенные DIV (.panels) и создаю для них новый объект базы данных через ajax. Затем я готовлю данные для отправки на сервер через ajax после завершения всех циклов. И мне нужно отправить эти данные после всех циклов с помощью ajax, потому что следующие вызовы ajax (которые я планирую сделать после итерации через .panels и подготовки данных) будут создавать другие объекты, которые будут связаны с созданными объектами. для .panel DIV (я помещаю все эти данные в массив ajaxes и планирую использовать их в дальнейшем).

Я использую отложенные объекты jQuery внутри цикла панелей, чтобы получить вновь созданный идентификатор панели и сохранить его в массиве ajaxes. Но я не знаю, как выполнить какой-либо код после цикла панелей.

Я попытался дать обещание (я новичок в этой технике) для всех вызовов ajax в конце ( $.ajax().promise().done ), но id, похоже, не работает. Иногда console.log в промисе срабатывает в конце, иногда в начале.

Я не специалист в jQuery и JS, поэтому хотел бы попросить пояснений, как работать с асинхронными вызовами ajax внутри циклов и что делать в этой ситуации? Я хочу выполнить некоторый код в конце, после того как все данные будут подготовлены.

Спасибо.


person mechpave    schedule 13.08.2015    source источник


Ответы (1)


Вы получите ответы, используя массивы промисов и оценивая их, используя оценку массива по сравнению с $.when и т. д., но есть удобный способ связать вызовы $.when с небольшими накладными расходами:

Псевдокод ниже:

var promise; // undefined is a resolved promise to $.when  
for (items in a loop){
    promise = $.when(promise, $.ajax({...});
}
promise.done(function(){
    // All done
});

Заметки:

  • $.ajax возвращает обещание. Это обещание состоит в том, чтобы перезвонить вам по завершении с данными или ошибкой.

  • $.when перезванивает вам, когда несколько обещаний выполнены (или когда одно из них не выполнено)

  • Если вы вызовете $.when с существующим обещанием и новым обещанием, вы получите третье обещание, которое завершится, когда оба будут выполнены. Они могут быть объединены в цепочку последовательно.

  • Недостатком этого сокращения является то, что окончательные значения данных, передаваемые в done, более сложны, чем ожидалось при обычной оценке массива обещаний по сравнению с done.

Я использую этот метод вместо массивов обещаний, когда мне просто нужно знать общее завершение, а не все отдельные данные/результаты. Это значительно упрощает код, а накладные расходы на дополнительные промисы минимальны. Он также отлично работает с наборами анимаций.

person Gone Coding    schedule 13.08.2015
comment
Спасибо. Я до сих пор не понимаю эту технику полностью, но я попытаюсь реализовать ее. - person mechpave; 13.08.2015
comment
Вы нигде не найдете ссылок на него, но вы увидите примеры .then() вызовов, объединенных в цепочку для последовательной работы. Я придумал это после того, как увидел цепочку then и немного поэкспериментировал. Надеюсь, поможет. - person Gone Coding; 13.08.2015