Я пытаюсь откатить несколько наборов статистических данных и отобразить сообщения о ходе выполнения после загрузки каждого набора данных в DOM.
Я пытаюсь использовать несколько отложенных функций вместе с функцией setTimeout для управления ответом пользователю.
Я начинаю вызывать функцию для отображения моего сообщения о загрузке.Затем я использую AJAX для получения данных.Затем функция успеха просматривает наборы данных и:
- Определяет текущий набор данных в переменной статистики
- Вызывает функцию loadDomElement (см. Пояснение ниже), которая возвращает обещание
- Вставляет возвращенное обещание в массив моих обещаний.
- Использует функцию .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.