0

我想避免在所有浏览器中无响应的 javascript。考虑到这一点是否可以编写代码?

详细信息:问题是目前有一个潜在的脚本块可以在我的 PC 上的 Chrome 中正常执行,但会导致 IE(各种版本)出现问题。最糟糕的是,我真的不确定它是否是那个脚本块。我会重写并解决这个问题。但是,我想知道在编码时应该避免什么。这个...

http://www.sitepoint.com/javascript-execution-browser-limits/

……读起来很有趣,但太笼统了。

编辑:我也在使用 jQuery/jQueryUI。

编辑 2:有一些模式/原则可用于避免特定问题。例如单例模式、PRG 模式、DRY 原则……等等。这种问题有类似的东西吗?

4

1 回答 1

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 的实现。使用这种风格,可以重写上面的例子,在计算过程中不阻塞 UI 线程,通过利用 Promise 和setInterval.

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();
}

第一个重要的区别是这个函数不再返回答案,而是一个答案的承诺。因此,使用代码可能如下所示:

howManyMultiplesOfFourBelow(10000000).done(function (multiples) {
    //Update the DOM with the answer (multiples)
});

更一般地回到您的问题,考虑您的代码有多少必须连续运行,以及是否有任何代码可能被延迟或分解以短暂释放 UI 线程。

于 2013-12-16T05:16:02.620 回答