我想避免在所有浏览器中无响应的javascript。 是否有可能在编写代码时编写代码?
详细信息:问题是目前有一个潜在的脚本块在我的PC上的Chrome中执行正常,但在IE(各种版本)上引起问题。最糟糕的是,我真的不确定它是否是那个脚本块。我会改写并解决这个问题。但是,我想在编码时知道我应该避免什么。此...
http://www.sitepoint.com/javascript-execution-browser-limits/
...是一个有趣的读物,但它太笼统了。
编辑:我也在使用jQuery / jQueryUI。
编辑2 :有一些模式/原则可用于避免特定问题。例如。单身模式,PRG模式,DRY原则......等等。对于这类问题,有类似的东西吗?
答案 0 :(得分:3)
我之前也遇到过这样的问题。
在编码时要记住的是我的代码在哪里开始执行,我的代码在哪里结束执行。对于这两点之间的所有时间,浏览器的UI线程被阻止,浏览器制造商可以理解地制定了反措施。
至于要避免什么,避免长时间连续循环。
这是一个极端的例子:
function howManyMultiplesOfFourBelow(foo) {
var i = 0, j = 0;
while (i < foo) {
i++;
if (i % 4 === 0) {
j++;
}
}
return j;
}
如果你将10,000,000传递给该函数,IE肯定会合适。围绕这种情况编程的方法不止一种;我更喜欢使用setTimeout
/ setInterval
分解代码。设置一个间隔并返回一个函数后,我们将UI线程释放回浏览器,浏览器负责按照我们的要求(或尽可能多的频率)执行间隔。
我将此与Futures/Promises结合使用;特别是jQuery's implementation。
使用此样式,可以重写上述示例,以便在计算期间通过利用promises和setInterval
来阻止UI线程。
function howManyMultiplesOfFourBelow(foo) {
var deferred = $.Deferred(),
interval,
i = 0,
j = 0;
interval = setInterval(function () {
if (i >= foo) {
clearInterval(interval);
deferred.resolve(j);
return;
}
i++;
if (i % 4 === 0) {
j++;
}
}, 1);
return deferred.promise();
}
第一个重要区别是此函数不再返回答案,而是返回答案的 promise 。因此,使用代码可能如下所示:
howManyMultiplesOfFourBelow(10000000).done(function (multiples) {
//Update the DOM with the answer (multiples)
});
更一般地回到你的问题,考虑你的代码必须连续运行多少,如果有任何代码可能被延迟或分解,以便简单地释放UI线程。