Как использовать отложенный в цикле for - PullRequest
0 голосов
/ 28 марта 2019

Я пытаюсь откатить несколько наборов статистических данных и отобразить сообщения о ходе выполнения после загрузки каждого набора данных в DOM.

Я пытаюсь использовать несколько отложенных функций вместе с функцией setTimeout для управления ответом пользователю.

Я начинаю вызывать функцию для отображения моего сообщения о загрузке.Затем я использую AJAX для получения данных.Затем функция успеха просматривает наборы данных и:

  1. Определяет текущий набор данных в переменной статистики
  2. Вызывает функцию loadDomElement (см. Пояснение ниже), которая возвращает обещание
  3. Вставляет возвращенное обещание в массив моих обещаний.
  4. Использует функцию .apply для передачи массива обещаний, а когда все обещания выполнены, он скрывает блок загрузки, чтобы показать все элементы, которые былизагружается в фоновом режиме.
$(function() {

        displayMyWaiter('Fetching month end statistics for all pitches....');

        $.ajax ( {
            url: '../../ajax/stats.php',
            method: 'GET',
            data: {mode: 'all statistics for ent',  statEntity: 'pitch', statType: 'total', statFilter: 'distinct'},
            dataType: 'json',
            type: 'POST',
            success: function(statGroup){
                console.log(statGroup);

                var promises = [];

                for (var i in statGroup) {

                    var stat = statGroup[i];
                    console.log(stat);
                    var def = $.Deferred();

                    $.when( loadDomElement(stat) ).done(function() {
                        console.log( "hello" );
                        def.resolve();
                        promises.push(def);
                    });

                };

                $.when.apply($, promises).done(function() {
                    hideMyWaiter("slide");
                });

            }       
        });        
    });

Функция loadDomElement получает текущий стат в качестве аргумента и возвращает обещание.По сути, он добавляет блок html на мою страницу.Затем он вызывает функцию loadStat, которая также возвращает обещание, которое разрешает отложенное в функции loadDomElement.Код выглядит следующим образом:

function loadDomElement(stat) {
        var dfd = $.Deferred();
        var statPanelID = 'stat_block_' + stat.code;
        $('#stats').append( '<div id="' + statPanelID + '"></div>' );

        $.when( loadStat(statPanelID, stat) ).done(function() {
            dfd.resolve();
        });

        return dfd.promise()
    }

Функция loadStat начинается с создания отложенной переменной outerDef.Затем он вызывает мою функцию для обновления сообщения в блоке загрузки.Это возвращает обещание:

function updateMyWaiter(str) {

        var text = "<li class='waiter-item'>" + str + "</li>"
        var dfd = $.Deferred();
        setTimeout(function(){ 
            $('.busyText').append(text);
            dfd.resolve();
        }, 3000);
        return dfd.promise();
    }

Когда обещание возвращается, оно вызывает функцию моей панели (которая также возвращает обещание) и использует мой пользовательский плагин для загрузки статистических данных на страницу (за сообщением «Загрузка»).).Функция выглядит следующим образом:

function loadStat(statPanelID, stat) {

        console.log("Now create stats for " + stat.code + ": " + stat.desc + " and place it in this block: " + statPanelID);
        var outerDef = $.Deferred();

        $.when( updateMyWaiter("Loading stats for " + stat.desc + "( code: " + stat.code + ")") ).done(function() {

            var panel = function() {

                var d = $.Deferred();
                var panelTitle = (stat.desc === null ? 'Pitch ' + stat.code : stat.desc);
                var statPluginID = 'stat_' + stat.code;

                $("#" + statPanelID).panIt({
                    allowScrolling: false,
                    header: {
                        title: panelTitle
                    },
                    body: {
                        content: '<div id="' + statPluginID + '">Position stat plugin for ' + stat.desc + ' here.</div>',
                        height:  '700'                                
                    },
                    onLoaded: function() {
                        $.when ( $('#' + statPluginID).stats({ // dom ID for stat plugin
                            statEntity: 'pitch',
                            statEntityID: stat.code,
                            statType: 'total',
                            statPeriod: null,
                            chartType: 'line',
                            chartTitle: 'Pitch stats for: ' + stat.desc,
                            activeTab: 'chart',
                            clickOptions: {
                                enabled: false
                            },
                            chartHeight: 700,
                            table: {
                                headers: [
                                    { name: 'Month', data: 'month' },
                                    { name: 'BF', data: 'bf' },
                                    { name: 'New', data: 'new_mem' },
                                    { name: 'Trn In', data: 'tra_in' },
                                    { name: 'Trn Out', data: 'tra_out' },
                                    { name: 'Lapsed', data: 'lapsed' },
                                    { name: 'CF', data:   'cf' },
                                    { name: 'Balance', data: 'balance'}
                                ],
                                hasSelect:  false,
                                search: false
                            }
                        })).done (function(result) {
                            d.resolve ('Pitch stats: ' + result);
                        });
                    }
                });
                return d.promise();

            };

            $.when ( panel() ).done (function(result) {
                console.log(result);
                outerDef.resolve(result); 
            });

        });

        return outerDef.promise();
    }

По сути, я хочу, чтобы приложение начиналось с моего внутреннего сообщения: «Выбор статистики конца месяца для всех этапов ....», а затем для каждой статистики должно обновляться загрузка.сообщение с другой строкой, в которой указано, какая статистика загружается.Как только вся статистика будет загружена, загрузочное сообщение должно быть скрыто.

Но происходит то, что я получаю первоначальное сообщение, которое отображается только в течение секунды, прежде чем оно будет скрыто.Затем приложение переходит к загрузке данных в DOM.

1 Ответ

0 голосов
/ 01 апреля 2019

Я нашел ответ в другом журнале: нажмите здесь

Я настроил свой код следующим образом:

$(function() {

        displayMyWaiter('Fetching month end statistics for all pitches....');

        $.ajax ( {
            url: '../../ajax/stats.php',
            method: 'GET',
            data: {mode: 'all statistics for ent',  statEntity: 'pitch', statType: 'total', statFilter: 'distinct'},
            dataType: 'json',
            type: 'POST',
            success: function(statGroup){
                handlePitchData(statGroup, 0); 
            }        
        });        

    });

function handlePitchData(statGroup, i) {

        if(i<statGroup.length){
            var stat = statGroup[i];
            console.log(statGroup[i]);
            $.when( loadDomElement(stat) ).done(function() {
                handlePitchData(statGroup, i+1);
            });    
        } else {
            hideMyWaiter("slide");
        }

    }



    function loadDomElement(stat) {
        var dfd = $.Deferred();
        var statPanelID = 'stat_block_' + stat.code;
        $('#stats').append( '<div id="' + statPanelID + '"></div>' );

        $.when( updateMyWaiter("Loading stats for " + stat.desc), loadStat(statPanelID, stat) ).done(function() {
            dfd.resolve();;
        });

        return dfd.promise();
    }

function loadStat(statPanelID, stat) {

        console.log("Now create stats for " + stat.code + ": " + stat.desc + " and place it in this block: " + statPanelID);
        var outerDef = $.Deferred();

        var panel = function() {

            var d = $.Deferred();
            var panelTitle = (stat.desc === null ? 'Pitch ' + stat.code : stat.desc);
            var statPluginID = 'stat_' + stat.code;

            $("#" + statPanelID).panIt({
                allowScrolling: false,
                header: {
                    title: panelTitle
                },
                body: {
                    content: '<div id="' + statPluginID + '">Position stat plugin for ' + stat.desc + ' here.</div>',
                    height:  '700'                                
                },
                onLoaded: function() {
                    $.when ( $('#' + statPluginID).stats({ // dom ID for stat plugin
                        statEntity: 'pitch',
                        statEntityID: stat.code,
                        statType: 'total',
                        statPeriod: null,
                        chartType: 'line',
                        chartTitle: 'Pitch stats for: ' + stat.desc,
                        activeTab: 'chart',
                        clickOptions: {
                            enabled: false
                        },
                        chartHeight: 700,
                        table: {
                            headers: [
                                { name: 'Month', data: 'month' },
                                { name: 'BF', data: 'bf' },
                                { name: 'New', data: 'new_mem' },
                                { name: 'Trn In', data: 'tra_in' },
                                { name: 'Trn Out', data: 'tra_out' },
                                { name: 'Lapsed', data: 'lapsed' },
                                { name: 'CF', data:   'cf' },
                                { name: 'Balance', data: 'balance'}
                            ],
                            hasSelect:  false,
                            search: false
                        }
                    })).done (function(result) {
                        d.resolve ('Pitch stats: ' + result);
                    });
                }
            });
            return d.promise();

        };

        $.when ( panel() ).done (function(result) {
            console.log(result);
            outerDef.resolve(result); 
        });

        return outerDef.promise();
    }


Короче говоря, я использовал рекурсивный метод.

...