Firefox在重for循环期间挂起
Firefox hangs during heavy for loop
当我的扩展开始一个繁重的工作(一个for
循环,将触发更多的进程),Firefox停止响应。在我的扩展完成任务之前,它不会恢复工作。
我的扩展需要大约16000毫秒来完成它的工作。是否有一种方法来执行我的脚本异步?还是有其他办法解决这个问题?
TL;DR:是的,有一个方法。使您的代码在短迭代中运行,并使用setTimeout
生成。
在JavaScript中没有线程这样的东西。好的,是的,这是Worker API。但是我仍然认为线程是不必要的和邪恶的(竞争条件,死锁,等等——这些在之前已经讨论过了)。浏览器扩展可能是JavaScript中线程可能有任何优点的唯一用例。但还是尽量避免。
。如果不是线程,那又是什么?JavaScript有一个事件循环,这是祸福参半。每次运行一段代码时,页面上的所有其他内容都会停止(这就是页面变得无响应的原因)。为了防止这种情况发生,您应该让每段代码尽可能快地运行,然后将让渡给事件队列中的其他事件。
要做到这一点,将for
循环替换为通过setTimeout
调用自身的递归函数。所以不用这个:
var length = collection.length; // <-- 2 gazillion
var i;
for (i=0; i<length; i+=1) {
lengthyOperation(i);
}
// Script yields here.
…您将执行如下操作:
var length = collection.length; // <-- still 2 gazillion
var i;
function lengthyOperationAsync() {
lengthyOperation(i); // <-- still lengthy
i += 1;
if (i < length) {
setTimeout(lengthyOperationAsync, 0);
}
// Script yields here.
}
这样,浏览器可以在冗长的for
循环迭代之间更新页面并处理用户输入。只有一个缺点:在某些浏览器中,它可能需要比平时更长的时间。这是因为计时器分辨率;当使用setTimeout
时,一些浏览器的最小延迟为4ms,即使您指定了0
。
顺便说一下,有一个名为setimmid的函数的建议,它就是为了这个确切的目的——但是大多数浏览器还没有实现它。
相关文章:
- JavaScript执行暂时挂起页面
- 是定义的操作系统睡眠/挂起期间setTimeout的行为
- Chrome浏览器“;挂起”;同时在循环中执行AJAX请求
- fullcalendar在删除导致浏览器挂起的多个事件时速度较慢
- 应用将图表转换为图像的jqplot代码时Chrome挂起
- 如何在不使用Internet Explorer的情况下从未挂起的HTML文件执行程序
- MongoDB collection.find()查询挂起
- 使用子字符串方法时应用程序挂起的原因
- 如何在AngularJS中取消挂起的请求
- 从node.js应用程序调用Mongoose Model.save()时挂起
- Chrome,Safari在从本地存储读取时挂起,而Firefox很好
- JS调试器是否挂起整个JS事件循环
- onbeforeunload 循环并挂起 Firefox
- big for循环挂起javascript引擎
- Firefox在重for循环期间挂起
- 简单的jquery每个循环使浏览器挂起
- Javascript - for循环挂起
- 谷歌可视化-用于循环挂起的Javascript
- Firefox 在无限循环中挂起,并忽略 window.print() 上的 css
- Node.js挂起多个setTimeout循环调用