我有一个大量使用 jQuery / JavaScript 的网络应用程序。它在内存中包含一个大型数组,用户可以通过键入文本框来过滤它。
问题:当过滤算法运行时,应用程序变得无法响应,浏览器甚至可能会询问用户是否让脚本继续运行。
最理想的情况是,我希望过滤器功能在单独的线程中运行,以避免无响应。这有可能吗?或者,我想展示一个旋转沙漏或类似的东西,但浏览器似乎无法在运行繁重的脚本时显示动画GIF。
攻击问题的最佳方法是什么?
答案 0 :(得分:3)
浏览器在主事件处理线程中执行脚本。这意味着任何长时间运行的脚本都可以保留浏览器队列。
您应该将过滤器逻辑拆分为块并在timeout回调上运行它们。您可以在执行之间使用0毫秒的间隙。 0 milli只是对浏览器的建议,但浏览器将使用后续回调之间的差距来清除其事件队列。超时通常是在浏览器环境中应该运行多长时间的脚本以防止页面“挂起”。
答案 1 :(得分:2)
这类工作是Web Workers的设计目标,支持是patchy, but improving。
答案 2 :(得分: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()
的调用周围添加传统循环)等等。