当前位置: 首页 > 面试题库 >

Javascript-如何避免在繁重的工作时阻塞浏览器?

廖夜洛
2023-03-14
问题内容

我的JS脚本中有这样的功能

function heavyWork(){
   for (i=0; i<300; i++){
        doSomethingHeavy(i);
   }
}

也许“
doSomethingHeavy”本身是可以的,但重复执行300次会导致浏览器窗口被卡住一段不可忽略的时间。在Chrome中,这并不是什么大问题,因为只有一个制表符有效。但对于Firefox来说,这是一场彻底的灾难。

有什么方法可以告诉浏览器/ JS“轻松一点”,而不是阻止对doSomethingHeavy的调用之间的所有操作?


问题答案:

您可以将呼叫嵌套setTimeout呼叫中:

for(...) {
    setTimeout(function(i) {
        return function() { doSomethingHeavy(i); }
    }(i), 0);
}

这会将对的调用排队,以doSomethingHeavy立即执行,但是可以在它们之间加入其他JavaScript操作。

更好的解决方案是让浏览器通过Web Workers产生一个新的非阻塞过程,但这是特定于HTML5的。

编辑:

setTimeout(fn, 0)实际上,使用时间要比零毫秒长得多-例如,Firefox强制执行最少4毫秒的等待时间。更好的方法可能是使用 setZeroTimeout,它更喜欢postMessage瞬时的,可中断的函数调用,但setTimeout可用作旧版浏览器的后备。



 类似资料:
  • 阻塞I/O的操作会导致App必须等待结果返回(阻塞结束)才能进行下一步操作。在UI线程上执行一个阻塞操作会将UI强行卡住,直接造成很糟糕的用户体验。 我们激活StrictMode后,我们开始收到了关于我们的App错误操作磁盘I/O的不良信息。 D/StrictMode StrictMode policy violation; ~duration=998 ms: android.os.Strict

  • 问题内容: 我发现我的某些活动在启动时被阻止。因此,我在一个新项目中编写了该代码: 结果是第一次创建AdView对象会阻塞UI线程1到2秒钟。 有什么办法可以避免这种情况? 谢谢 问题答案: 您正在UI线程中创建AdView,这就是被阻止的原因。在AdView初始化期间,线程不会执行其他任何操作。 您可以尝试在另一个线程中加载AdView,也可以使用AsyncTask以用户界面安全的方式加载它。

  • 问题内容: 考虑以下代码: 我了解在上面的代码中,如果拥有同步块的所有权,并且同时如果线程尝试获取同步块,则需要内核等待。我想避免这种情况,并在块之前旋转,直到调用等待并离开该块的所有权为止。那可能吗? 问题答案: JVM无需将进入锁定的同步块的步骤实现为硬块和上下文切换。它可以选择使用重量更轻的方法,例如旋转锁。实际上,Oracle JVM竭尽所能避免阻塞。因此,您可能会发现JVM已经为您完成了

  • 我安装了一个插件,允许我从代码中创建UML图。一切正常,直到我发现现在所有的键盘快捷键(如CTRL-X、CTRL-Z、CTRL-SPACE、CTRL-SHIFT-F等)除了CTRL-C和CTRL-V之外,现在需要单击右下角显示的小正方形。这是每一次都需要的。 这是出现的正方形的几个例子: 如果我点击消息或按回车键,我可以访问该功能。有人知道如何摆脱这个烦人的东西或者至少重置Eclipse相关的配置

  • 问题内容: 我正在纯粹用JavaScript开发OAuth身份验证流程,我想在弹出窗口中向用户显示“授予访问权限”窗口,但是该窗口被阻止了。 如何防止由或创建的弹出窗口被不同浏览器的弹出窗口阻止程序阻止? 问题答案: 一般规则是,如果从 直接用户操作 未调用的javascript中调用了javascript或类似方法,则会阻止弹出窗口阻止 程序 。也就是说,您可以响应单击按钮而调用,而不会被弹出窗

  • 我的web项目一旦有前端页面的更新就需要清理浏览器缓存后才能看到最新效果,有时不清理不但不能看到最新效果还会出现页面布局错乱,如何能避免这种情况,我想要更新前端页面,用户也不需要清理浏览器缓存,页面关闭重新打开就能显示最新效果