這個項目已經幫助解決了我一直在努力的一個應用程序中的一個大難題,所以感謝發佈它。 AdjustTickCount實用程序是驗證解決方案的絕佳必備工具,因此也贊同此舉。
該問題也影響IE 7,它也似乎影響IE 6,但隨着瀏覽器停止全部響應並且該解決方案似乎無法在該版本上運行,結果會更糟。這些舊版本的用戶仍然很多,特別是在商業/企業領域。
我沒有發現鼠標左鍵是Windows XP中的一個因素,沒有它就會出現問題。
如果超時延遲最重要的是秒數,並且應用程序中設置的超時時間很少,前兩個答案都可以。如果需要更多和更長的超時時間,則需要做更多工作來防止Web應用程序無法使用。在Web 2中。0使用諸如qooxdoo之類的框架的RIA可能使其運行數天,因此可能需要更多和更長的超時而不是半秒的延遲來產生動畫或其他短暫效果。
第一種解決方案是一個好的開始,但將下一個超時設置爲target-now
將再次導致該函數被立即調用,因爲它仍然會使正常運行時間+延遲超過2^32毫秒,因此JS代碼將旋轉,直到正常運行時間包裝到0(或用戶殺死瀏覽器)。
第二種解決方案是一種改進,因爲直到現在是正常運行時間包1秒左右,它允許其他代碼,來看看,在之內,但實驗表明,仍然可以過早超時將僅在1秒的間隔發生如果有足夠的暫停超時播放,足以使瀏覽器無法使用。它會一直持續到正常運行時間結束,所以如果請求的延遲時間足夠長,用戶仍然可能決定終止瀏覽器。
較少耗費CPU的解決方案是將每個後續超時的延遲設置爲前一延遲的一半,直到該延遲小於500毫秒,此時我們知道即將發生正常運行的環繞點(< 1秒),並且我們可以將下一個超時設置爲target-now
,以便過早超時檢查在僅僅少量的其他週期後停止。達到這一程度需要多長時間取決於原始延遲的時間長短以及當調用setSafeTimeout
時的正常運行時間週期有多接近,但最終以最小的CPU負載,應用程序恢復正常行爲而用戶沒有經歷任何長時間的減速。
事情是這樣的:
function setSafeTimeout(func, delay) {
var target = +new Date + delay;
var newDelay = delay;
var helper = function()
{
var now = +new Date;
if (now < target)
{
newDelay /= 2; // halve the wait time and try again
if(newDelay < 500) // uptime wrap around is imminent
{
newDelay = target-now; // go back to using original target
}
var handle = setTimeout(helper, newDelay);
// if required record handle somewhere for clearTimeout
}
else
{
func();
}
};
return setTimeout(helper, delay);
};
進一步細化:
我發現setTimeout()
有時可以調用回調早幾毫秒甚至當系統正常運行時間滴答比預期不是接近2 ^爲32ms。在這種情況下,上述函數中使用的下一個等待時間間隔可能大於原始目標的剩餘時間,這會導致等待時間超過最初期望的時間。
下面是另一個版本,從而解決了這個問題:
function setSafeTimeout(func, delay) {
var target = +new Date + delay;
var newDelay = delay;
var helper = function()
{
var now = +new Date;
if (now < target)
{
var timeToTarget = target-now;
newDelay /= 2; // halve the wait time and try again
if(newDelay < 500 || newDelay > timeToTarget) // uptime wrap around is imminent
{
newDelay = timeToTarget; // go back to using original target
}
var handle = setTimeout(helper, newDelay);
// if required record handle somewhere for clearTimeout
}
else
{
func();
}
};
return setTimeout(helper, delay);
};
有沒有問題?你在尋找解決方法還是與世界分享? – 2010-12-04 00:45:01
Sooo ...你基本上是說在系統正常運行25天之後做24小時超時會有問題嗎?我想知道我什麼時候需要這樣的超時? – 2010-12-04 01:03:02
這更多地記錄了IE8中的一個錯誤。舉例來說,這可能是一個問題,比如你在一個小時後有一個定時器觸發,當用戶觸發時將用戶重定向到另一個頁面。當您在2^32毫秒的正常運行時間的一小時內,計時器將立即啓動,用戶將無法訪問原始頁面。一旦正常運行時間通過2^32毫秒,所有事情都會再次開始工作。但是那一個小時,頁面就會被打破。 – user281806 2010-12-04 01:21:39