我必须加载一个非常大的JSON对象并执行各种昂贵的进程。出于这个原因,我正在显示一个进度条,总共增加五次。如果我必须加载10000个项目,它将每2000次更新等等。
问题是效果不可见,因为所有堆栈在整个功能完成后执行,而不是每过程20%更新进度条。如果我尝试加载10000个项目或200万个项目,发生相同的事情,并且通过控制台日志之间的计算延迟来判断,则肯定有足够的处理时间来显示可见的进度效果。也许我不理解javascript(我知道这不是这样做的方式)。如何跟踪昂贵的流程并正确显示可见的进度条效果?
使用
登录用户名:admin
密码:testit
var initItems = function(publicationItems) {
var publications = new Array();
var numberOfItems = goog.object.getCount(publicationItems);
var minStep = 20;
var currentProgress = 20;
var progressBarStep = parseInt(numberOfItems / 5);
var i = 0;
goog.object.forEach(publicationItems, function() {
var currentName = publicationItems.name;
var currentCat = publicationItems.categories;
// Insert clear div to break line after every 5 items.
if (i % 5 == 0 && i != 0)
publications.push(this.clear);
if(i % progressBarStep == 0)
{
progressBar.setValue(currentProgress);
console.log(i + ' ' + progressBarStep + ' ' + currentProgress + ' ' + progressBar.getValue());
currentProgress += minStep;
}
i++;
publications.push(goog.dom.createDom('div', {
'style' : 'width:' + this.currentPublicationDimension + 'px;height:' +
this.currentPublicationDimension + 'px;border:1px solid #B3B3B3;' +
'float: left;margin-top: 5px;background-color: #FCFCFC;' +
'max-width:' + this.currentPublicationDimension + 'px;max-height:' +
this.currentPublicationDimension + 'px;_height:' +
this.currentPublicationDimension +
'px;_width:' + this.currentPublicationDimension + 'px;margin-left:' +
this.publicationLeftMargin + 'px;',
'class' : 'publication'
}, currentName, currentCat));
}, this);
return publications;
};
调用此函数的上下文:
// Bind COMPLETE event listener to ajaxHandler.
goog.events.listen(ajaxHandler, goog.net.EventType.SUCCESS,
goog.bind(function(e) {
//goog.style.showElement(progressBarContainer, false);
goog.dom.append(this.mainViewPublications, initItems.call(this, e.target.getResponseJson()));
}, this), false, this);
答案 0 :(得分:1)
问题是JavaScript是Singlethreaded并且首先尝试执行计算。 ProgressBar是异步的,只有在线程不忙时才会更新。
你可以使用如下的回调
function a () {
/* do one iteration */
progressBar.setValue(currentProgress);
goog.Timer.callOnce(a, 10);
}
问题在于,你不能将参数传递给函数,你必须使用全局变量(或者至少是'对象'宽变量)。
我目前遇到同样的问题,并没有找到一个非常好的解决方案。所以这是第一种方法。如果我找到另一个解决方案,我会在这里更新。