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 и планирам да ги използвам в).

Използвам отложени обекти на jQuerys в цикъла на панелите, за да получа новосъздадения идентификатор на панела и да го задържа в масива на 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