我已阅读帖子 here关于在密集 DOM 处理(使用 JavaScript)期间使用 setTimeout(),但如何将此函数与以下代码集成?下面的代码适用于少量选项,但当选项数量太大时,我的“请稍候”动画 GIF 在本地 JavaScript 处理时会卡住。谢谢!
function appendToSelect() {
$("#mySelect").children().remove() ;
$("#mySelect").html(
'<option selected value="' + obj.data[0].value + '">'
+ obj.data[0].name
+ '</option>'
);
var j = 1 ;
for (var i = 1; i < obj.data.length; i++) {
$("#mySelect").append(
'<option value="' + obj.data[i].value + '">'
+ obj.data[i].name
+ '</option>'
);
}
}
最佳答案
这是一个解决方案:
function appendToSelect() {
$("#mySelect").children().remove();
$("#mySelect").html(
'<option selected value="'+obj.data[0].value+'">'
+ obj.data[0].name
+ '</option>'
);
obj.data.splice(0, 1); // we only want remaining data
var appendOptions = function() {
var dataChunk = obj.data.splice(0, 10); // configure this last number (the size of the 'chunk') to suit your needs
for(var i = 0; i < dataChunk.length; i++) {
$("#mySelect").append(
'<option value="' + dataChunk[i].value + '">'
+ dataChunk[i].name
+ '</option>'
);
}
if(obj.data.length > 0) {
setTimeout(appendOptions, 100); // change time to suit needs
}
};
appendOptions(); // kicks it off
}
不如@Borgar's那么优雅解决方案,但你明白了。基本上,我正在做同样的事情,但都是在你的一个函数中,而不是像他那样将其分解为一个高阶函数。我喜欢他的解决方案,但如果您不喜欢,也许这对您有用。
<小时/>编辑:对于那些没有立即看到它的人,此解决方案和 @Borgar's 之间的主要区别之一该解决方案允许您设置每次超时之间处理的数据“ block ”的大小。 @Borgar's处理数组的每个成员后超时。如果我有时间,我会尝试创建一个高阶函数来处理这个问题,这样它会更优雅。但没有 promise ! ;)
<小时/>编辑:所以,这是我对 @Borgar's 的改编解决方案,它允许更轻松地设置“ block ”大小并配置超时值:
function incrementallyProcess(workerCallback, data, chunkSize, timeout, completionCallback) {
var itemIndex = 0;
(function() {
var remainingDataLength = (data.length - itemIndex);
var currentChunkSize = (remainingDataLength >= chunkSize) ? chunkSize : remainingDataLength;
if(itemIndex < data.length) {
while(currentChunkSize--) {
workerCallback(data[itemIndex++]);
}
setTimeout(arguments.callee, timeout);
} else if(completionCallback) {
completionCallback();
}
})();
}
function appendToSelect() {
$("#mySelect").children().remove();
$("#mySelect").html(
'<option selected value="' + obj.data[0].value + '">'
+ obj.data[0].name
+ '</option>'
);
obj.data.splice(0,1); // we only want remaining data
incrementallyProcess(function(data) {
$("#mySelect").append(
'<option value="' + data.value + '">'
+ data.name
+ '</option>'
);
}, obj.data, 10, 100, removeAnimatedGifFunction); // last function not required...
}
希望有所帮助 - 我认为这结合了两种解决方案的优点。 注意,第二个匿名函数不再使用索引值,而是简单地传入整个对象(带有value和name属性);这使得它更干净一些,因为在迭代事物时,当前对象的索引通常并不那么有用,IMO。
我确信仍然可以做一些事情来使其变得更好,但这留给读者作为练习。 ;)
关于javascript - 在密集的 JavaScript 处理过程中,如何将控制权(短暂地)交还给浏览器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/210821/