在我的应用程序中,我发现了一些使用setInterval0毫秒的JavaScript代码,如下所示:
self.setInterval("myFunction()",0);
Run Code Online (Sandbox Code Playgroud)
显然,这对我来说似乎不是一个好主意.谁能告诉我setInterval这里的行为会是什么?("myFunction"对服务器进行AJAX调用)
我问这个是因为我的申请表现不正常.90%的情况下,应用程序运行正常,并且只对服务器进行一次调用.但有时会对服务器进行多次调用(到目前为止,最多只有48次调用),我几乎可以肯定这是这行代码的错误.
我有一个长期运行的功能.它遍历一个大型数组并在每个循环中执行一个函数.
longFunction : function(){
var self = this;
var data = self.data;
for(var i=0; len = data.length; i<len; i++){
self.smallFunction(i);
}
},
smallFunction : function(index){
// Do Stuff!
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这很好,但是当我处理大约1500左右的数组时,我们得到了接收javascript执行警报消息的点.
所以我需要打破这个.我的第一次尝试是这样的:
longFunction : function(index){
var self = this;
var data = self.data;
self.smallFunction(index);
if(data.slides[index+1){
setTimeout(function(){
self.longFunction(index+1);
},0);
}
else {
//WORK FINISHED
}
},
smallFunction : function(index){
// Do Stuff!
}
Run Code Online (Sandbox Code Playgroud)
所以在这里我将删除循环并引入一个自我调用函数,它会在每次迭代时增加其索引.要将控制权返回给主UI线程以防止javascript执行警告方法,我已经添加了一个setTimeout允许它在每次迭代后更新的时间.问题在于,通过这种方法,实际完成的工作需要花费10倍的时间.似乎正在发生的事情虽然setTimeout设置为0,但它实际上等待的时间更长,为10毫秒.哪个在大型阵列上很快就会建立起来.删除setTimeout和longFunction释放调用本身可以提供与原始循环方法相当的性能.
我需要另一个解决方案,一个具有与循环相当的性能但不会导致javascript执行警告的解决方案.不幸的是,webWorkers不能在这种情况下使用.
值得注意的是,在此过程中我不需要完全响应的UI.足以每隔几秒更新一次进度条.
将它分解成块的循环是一种选择吗?即,一次执行500次迭代,停止,超时,更新进度条,执行下一次500等等.
有更好的吗?
回答:
唯一的解决方案似乎是将工作分块.
通过将以下内容添加到我的自我调用函数中,我允许UI每250次迭代更新:
longFunction : function(index){ …Run Code Online (Sandbox Code Playgroud)