我想避免在所有浏览器中出现无响应的 JavaScript。 是否可以在编写代码时考虑到这一点?
详细信息:问题是,目前有一个潜在的脚本 block 可以在我的 PC 上的 Chrome 中正常执行,但在 IE(各个版本)上会导致问题。最糟糕的是我真的不确定它是否是那个脚本 block 。我会重写并解决这个问题。但是,我想知道在编码时我到底应该避免什么。这...
http://www.sitepoint.com/javascript-execution-browser-limits/
...读起来很有趣,但太笼统了。
编辑:我也在使用 jQuery/jQueryUI。
编辑 2:可以使用一些模式/原则来避免特定问题。例如。单例模式、PRG模式、DRY原则……等等。对于这种问题有类似的东西吗?
最佳答案
我以前也遇到过这样的问题。
编码时要记住的事情是我的代码从哪里开始执行,以及我的代码在哪里结束执行。在这两点之间的所有时间里,浏览器的 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 。 使用这种风格,可以重写上面的示例,通过利用 Promise 和 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 线程。
关于javascript - 避免脚本无响应的跨浏览器方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17912958/