在密集的JavaScript处理过程中,如何(短暂地)将控制权交还给浏览器?
我已经读过关于在密集DOM处理(使用JavaScript)期间使用setTimeout()的文章,但是如何将此函数与下面的代码集成?下面的代码适用于少量选项,但当选项数量过大时,我的“请等待”动画GIF会在本地JavaScript处理时冻结。谢谢在密集的JavaScript处理过程中,如何(短暂地)将控制权交还给浏览器?,javascript,jquery,Javascript,Jquery,我已经读过关于在密集DOM处理(使用JavaScript)期间使用setTimeout()的文章,但是如何将此函数与下面的代码集成?下面的代码适用于少量选项,但当选项数量过大时,我的“请等待”动画GIF会在本地JavaScript处理时冻结。谢谢 function appendToSelect() { $("#mySelect").children().remove() ; $("#mySelect").html( '<option selected val
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>'
);
}
}
函数appendToSelect(){
$(“#mySelect”).children().remove();
$(“#mySelect”).html(
''
+对象数据[0]。名称
+ ''
);
var j=1;
对于(变量i=1;i
您需要重写函数以缓存元素列表,然后使用某种计数器在列表上循环
然后,当计数器在\u wait==0之前到达计数器%max\u num\u时,调用函数本身的超时
确保清除完整列表末尾的缓存和计数器,或使用带有额外计数参数的辅助函数。恰好我刚才发布了关于此的内容。下面是一个定时循环函数:
function processLoop( actionFunc, numTimes, doneFunc ) {
var i = 0;
var f = function () {
if (i < numTimes) {
actionFunc( i++ ); // closure on i
setTimeout( f, 10 )
}
else if (doneFunc) {
doneFunc();
}
};
f();
}
函数processLoop(actionFunc、numTimes、doneFunc){
var i=0;
var f=函数(){
如果(i
对于您的情况,可以这样使用:
function appendToSelect () {
$("#mySelect").children().remove() ;
$("#mySelect").html(
'<option selected value="' + obj.data[0].value + '">'
+ obj.data[0].name
+ '</option>'
);
var j = 1 ;
processLoop(function (i){
$("#mySelect").append(
'<option value="' + obj.data[i].value + '">'
+ obj.data[i].name
+ '</option>'
);
}, obj.data.length);
}
函数appendToSelect(){
$(“#mySelect”).children().remove();
$(“#mySelect”).html(
''
+对象数据[0]。名称
+ ''
);
var j=1;
processLoop(函数(i){
$(“#mySelect”).append(
''
+对象数据[i].名称
+ ''
);
},对象数据长度);
}
您需要确保对迭代函数中的obj变量具有闭包或其他访问权限
希望这有帮助。这里有一个解决方案:
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
}
函数appendToSelect(){
$(“#mySelect”).children().remove();
$(“#mySelect”).html(
''
+对象数据[0]。名称
+ ''
);
splice(0,1);//我们只需要剩余的数据
var appendOptions=function(){
var dataChunk=obj.data.splice(0,10);//配置最后一个数字(“chunk”的大小)以满足您的需要
对于(var i=0;i0){
setTimeout(appendOptions,100);//根据需要更改时间
}
};
appendOptions();//启动它
}
没有解决方案那么优雅,但你明白了。基本上,我在做同样的事情,但都是在你的一个函数中,而不是像他那样把它分解成一个高阶函数。我喜欢他的解决方案,但如果你不喜欢,也许这对你有用
编辑:对于那些没有立即看到它的人来说,此解决方案和的主要区别之一是,此解决方案允许您设置在每个超时之间处理的数据“块”的大小。处理阵列的每个成员后超时。如果我有时间,我会尝试创建一个高阶函数来处理这个问题,这样它会更优雅。但是没有承诺!;)
编辑:下面是我对解决方案的修改,它允许设置“块”大小并更轻松地配置超时值:
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...
}
function incrementallyProcess(workerCallback、数据、chunkSize、超时、completionCallback){
var itemIndex=0;
(功能(){
var remainingDataLength=(data.length-itemIndex);
var currentChunkSize=(remainingDataLength>=chunkSize)?chunkSize:remainingDataLength;
if(itemIndex
希望这能有所帮助——我认为这是两种解决方案的最佳结合注意,第二个匿名函数不再使用索引值,而是简单地传入整个对象(带有值和名称属性);这使得它更简洁,因为当前对象的索引在迭代对象时通常并不那么有用
我相信还有一些事情可以做得更好,但这是留给读者的练习 如果您需要更简单的东西,我编写了一个jQuery插件来简化异步循环的编写: 使用该插件,您的代码可以重写为:
function appendToSelect() {
$("#mySelect").children().remove() ;
$("#mySelect").html(
'<option selected value="' + obj.data[0].value + '">'
+ obj.data[0].name
+ '</option>'
);
/////////////////////////////
var i = 1;
$.whileAsync({
test: function(){ i < obj.data.length; }
loop: function()
{
$("#mySelect").append(
'<option value="' + obj.data[i].value + '">'
+ obj.data[i].name
+ '</option>'
);
i++;
}
});
/////////////////////////////
}
函数appendToSelect(){
$(“#mySelect”).children().remove();
$(“#mySelect”).html(
''
+对象数据[0]。名称
+ ''
);
/////////////////////////////
var i=1;
$.whileAsync({
测试:函数(){i
应该有助于提高反应能力。调整“批量”和“延迟”选项以获得更多控制。告诉他们使用Chrome,他们将拥有JITted javascript:)