我有一个大量使用jQuery/JavaScript的 Web 应用程序。它在内存中保存一个大数组,用户通过在文本框中输入来过滤它。
问题:当过滤算法运行时,应用程序变得无响应,浏览器甚至可能询问用户是否让脚本继续运行。
理想情况下,我希望过滤器函数在单独的线程中运行,以避免无响应。这有可能吗?或者,我想展示一个旋转的沙漏或类似的东西,但是浏览器在运行繁重的脚本时似乎无法显示动画 GIF。
解决问题的最佳方法是什么?
我有一个大量使用jQuery/JavaScript的 Web 应用程序。它在内存中保存一个大数组,用户通过在文本框中输入来过滤它。
问题:当过滤算法运行时,应用程序变得无响应,浏览器甚至可能询问用户是否让脚本继续运行。
理想情况下,我希望过滤器函数在单独的线程中运行,以避免无响应。这有可能吗?或者,我想展示一个旋转的沙漏或类似的东西,但是浏览器在运行繁重的脚本时似乎无法显示动画 GIF。
解决问题的最佳方法是什么?
浏览器在主事件处理线程中执行脚本。这意味着任何长时间运行的脚本都会阻塞浏览器队列。
您应该将过滤器逻辑拆分为块并在超时回调上运行它们。您可以在执行之间使用 0 米的间隙。0 毫秒只是给浏览器的一个建议,但是浏览器会利用后续回调之间的间隙来清除它的事件队列。超时通常是应该在浏览器环境中执行多长时间运行脚本以防止页面“挂起”。
这种类型的工作是Web Workers的设计目标,支持不完整,但在改进.
扩展我之前的评论,假设您正在处理一个数组,您可能正在使用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()
)等。