Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript执行会暂时挂起页面_Javascript_Jquery_Freeze - Fatal编程技术网

JavaScript执行会暂时挂起页面

JavaScript执行会暂时挂起页面,javascript,jquery,freeze,Javascript,Jquery,Freeze,我有一个web应用程序,它大量使用jQuery/JavaScript。它在内存中保存一个大数组,用户通过在文本框中键入来过滤它 问题:当过滤算法运行时,应用程序变得无响应,浏览器甚至可能询问用户是否让脚本继续 最佳情况下,我希望filter函数在一个单独的线程中运行,以避免无响应。这有可能吗?或者,我想显示一个旋转沙漏或类似的,但浏览器似乎无法显示动画GIF时,运行沉重的脚本 解决此问题的最佳方法是什么?此类型的作业是为支持而设计的。浏览器在主事件处理线程中执行脚本。这意味着任何长时间运行的脚本

我有一个web应用程序,它大量使用jQuery/JavaScript。它在内存中保存一个大数组,用户通过在文本框中键入来过滤它

问题:当过滤算法运行时,应用程序变得无响应,浏览器甚至可能询问用户是否让脚本继续

最佳情况下,我希望filter函数在一个单独的线程中运行,以避免无响应。这有可能吗?或者,我想显示一个旋转沙漏或类似的,但浏览器似乎无法显示动画GIF时,运行沉重的脚本


解决此问题的最佳方法是什么?

此类型的作业是为支持而设计的。

浏览器在主事件处理线程中执行脚本。这意味着任何长时间运行的脚本都可能阻塞浏览器队列


您应该将过滤器逻辑分割成块,并在回调函数上运行它们。您可以在执行之间使用0 mills的间隙。0 milli只是对浏览器的建议,但浏览器将使用后续回调之间的间隔来清除其事件队列。超时通常是指在浏览器环境中运行的脚本应执行多长时间,以防止页面“挂起”。

根据我前面的评论展开,考虑到您正在处理数组,您可能正在使用
for
循环。您可以轻松地重构一个简单的
for
循环,以使用
setTimeout()
,从而将工作分解为块,浏览器有机会处理屏幕绘制和每个块之间的用户交互。简单的例子:

// Generic function to execute a callback a given number
// of times with a given delay between each execution
function timeoutLoop(fn, startIndex, endIndex, delay) {
    function doIteration() {
        if (startIndex < endIndex){
            fn(startIndex++);
            setTimeout(doIteration, delay);
        }
    }
    doIteration();
}

// pass your function as callback
timeoutLoop(function(i) {
   // current iteration processing here, use i if needed;
}, 0, 100, 0);
//执行给定数字的回调的通用函数
//每次执行之间具有给定延迟的次数
函数timeoutLoop(fn、startIndex、endIndex、delay){
函数doIteration(){
if(开始索引<结束索引){
fn(startIndex++);
setTimeout(doIteration,delay);
}
}
doIteration();
}
//将函数作为回调传递
timeoutLoop(功能(i){
//这里的当前迭代处理,如果需要,使用i;
}, 0, 100, 0);
演示:


这只是我拼凑起来展示一般想法的东西,但显然它可以以各种方式扩展,例如,您可能想在
timeoutLoop()
中添加
chunkSize
参数,以说明每个超时中要进行多少次循环迭代(围绕
fn()
的调用添加一个常规循环),等等。

使用数据库/文件并进行AJAX调用,而不是将其保存在用户内存中,这样可以使其异步,然后就不会出现阻塞。Web workers可能()@Dan Lee:这是真的,但这将迫使我对应用程序进行重大重写。(除非使用Web workers)JS在单个线程中运行,浏览器用于更新页面的同一线程。您可以重写过滤算法,使用
setTimeout()
将处理过程分解为更小的块,并让浏览器有机会在每个块之间做出响应。这种技术还避免了浏览器显示的长时间运行的脚本提示。@Ilia Frenkel:谢谢你的提示。我来看看。似乎对它的支持是零碎的。谢谢,这对我来说是新的。我会看一看的。@codebox,Web Worker上的巨大处理也挂在Chrome(v34)上是的,正如上面@nnnn所建议的,我认为这是避免无响应的最合理的方法。我想,当主要浏览器支持Web Workers时,Web Workers将是一条出路。@Gruber不幸的是,IE还没有它。作为记录,我成功地运用了这种方法来解决我的问题。IE应该被视为一个主要的浏览器,如果你希望你的大多数访问者都是senor citizens。我用你的想法来解决我的问题。结果真的很好。