是什么原因导致setTimeout崩溃浏览器,以及如何安全地使用它?

时间:2016-02-25 02:52:19

标签: javascript html5 multithreading

我在HTML5中构建一个依赖于setTimeout事件的游戏,在用户播放时逐渐生成一个基于图块的大型地图(而不是强迫用户等待1分钟以上世界创世纪完成)。游戏以非常接近的间隔调用setTimeout数千(甚至数万)次。每个线程完成后,它会递归调用setTimeout,直到满足基本情况。

尽管如此,尽管游戏相当具有图形密集性(使用WebGL),但它运行得相当好,即使在移动设备上也是如此。但是,在几秒钟到几分钟之后,浏览器有时会崩溃。

The actual page crashes (not a JavaScript bug per se).

我有几个关于为什么会发生这种情况的理论,但如果我继续使用这种技术,我想确保我更好地理解这个问题。

  • 是因为我有太多线程同时进行?奇怪的是,这个问题有时需要多达10分钟(如果我禁用基本情况) - 所以在那段时间它与所有线程运行良好但随后突然爆炸(尽管它们在0到100毫秒之间的随机间隔被调用)。

  • 是否因为setTimeout不允许从堆栈中释放内存?这似乎对我来说很遥远,但它可以解释事情。如果启用了基本案例检测,程序通常不会崩溃(但偶尔会发生)。

  • 浏览器是否可能存在错误,导致每次通话无法正常清理?

  • 是因为浏览器出现故障并安排两个setTimeout在同一时间运行?

  • 是因为浏览器检测到可能的无限循环?

  • 是因为当setTimeout被触发但没有及时完成时,js代码正在运行,导致延迟/过期超时(或者其中一些超时)?

最后,有没有办法安全地使用setTimeout,这样当我为其他人部署游戏时我不必担心这个问题?

3 个答案:

答案 0 :(得分:0)

您是否尝试过使用setInterval来查看是否出现同样的问题?

答案 1 :(得分:0)

这一直困扰着我。我在jsfiddle上做了以下事情:

function killtime(){
    for(var i = 0; i < 2000000000; i++);
}

for(var j = 0; j < 1000000; j++){
    setTimeout(killtime(), 1);
}

没有崩溃。这比我的程序产生更多超时阻塞。所以这对单独的setTimeout来说不是问题。我现在认为问题可能是setTimeouts调用了很多阻塞代码,这些代码可能会以某种方式干扰我依赖的某些WebGl库的时序要求 - 这只是一个最好的猜测。如果不在调试环境中运行Chrome,则无法隔离此问题。并且在更简单的程序中很难再现这个问题。我注意到移动浏览器比桌面浏览器更容易崩溃,所以我肯定会在那里做很多调试。

我可以说的是setTimeout函数本身可能没有任何问题(至少不是直接)。

答案 2 :(得分:0)