javascript - 避免脚本无响应的跨浏览器方法

标签 javascript

我想避免在所有浏览器中出现无响应的 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/

相关文章:

javascript - 如何将虚拟 jQuery 对象传递给 Javascript 函数

javascript - React(next js) 类组件起作用。 Prop 怎么办?

javascript - Ajax json正确显示数据

javascript - 在 JavaScript 中使用 this.prototype.show

javascript - node.js 中的并行回调宇宙?

javascript - Promise 内部的 Promise 在 bluebird Nodejs 中创建难以管理的结构

javascript - 在 ES6 中创建带箭头或不带箭头的顶级函数的优缺点是什么?

javascript - 如何使用 # 创建动态页面?

javascript - 如何处理从backbone.js中的collection.create()触发的多个无效事件

javascript - 一遍又一遍地将相同的选项传递给 jQuery 函数