这是一个解决方案:
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 的解决方案那么优雅,但你明白了。基本上,我正在做同样的事情,但都在你的一个函数中,而不是像他那样将它分解成一个更高阶的函数。我喜欢他的解决方案,但如果你不喜欢,也许这对你有用。
编辑:对于那些没有立即看到它的人,此解决方案与@Borgar 的主要区别之一是此解决方案允许您设置在每次超时之间处理的数据“块”的大小。@Borgar在处理数组的每个成员后超时。如果我有时间,我会尝试创建一个高阶函数来处理这个问题,这样它就更优雅了。虽然没有Promise!;)
编辑:所以,这是我对@Borgar解决方案的改编,它允许设置“块”大小并更轻松地配置超时值:
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。
我相信还有一些事情可以做来使这更好,但这留给读者作为练习。;)