5

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

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

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

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

4

3 回答 3

3

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

您应该将过滤器逻辑拆分为块并在超时回调上运行它们。您可以在执行之间使用 0 米的间隙。0 毫秒只是给浏览器的一个建议,但是浏览器会利用后续回调之间的间隙来清除它的事件队列。超时通常是应该在浏览器环境中执行多长时间运行脚本以防止页面“挂起”。

于 2012-09-14T07:06:18.833 回答
2

这种类型的工作是Web Workers的设计目标,支持不完整,但在改进.

于 2012-09-14T07:02:01.247 回答
2

扩展我之前的评论,假设您正在处理一个数组,您可能正在使用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);

演示:http: //jsfiddle.net/nnnnnn/LeZxM/1/

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

于 2012-09-14T07:50:34.350 回答