2011-10-16 60 views
7

下面的測試基本上〜1000的數學運算和大多數PC和Android瀏覽器,而iOS 4.x版上正常工作在iOS5 safari(iPhone 4和iPad 2)上,我們得到「JavaScript:錯誤未定義JavaScript執行超時」。任何幫助非常感謝謝謝。的Javascript IOS5「JavaScript執行超過超時」

/** Converts numeric degrees to radians */ 
if (typeof (Number.prototype.toRad) === "undefined") { 
    Number.prototype.toRad = function() { 
    return this * Math.PI/180; 
    } 
} 

function gc(lat1, lon1, lat2, lon2) { 
    // returns the distance in km between a pair of latitude and longitudes 
    var R = 6371; // km 
    var dLat = (lat2 - lat1).toRad(); 
    var dLon = (lon2 - lon1).toRad(); 
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
     Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) * 
     Math.sin(dLon/2) * Math.sin(dLon/2); 
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
    var d = R * c; 
    return d; 
} 

function test() { 
    var d1 = new Date(); 
    var lat1, lon1, lat2, lon2; 
    lat1 = -36; 
    lon1 = 174; 

    lat2 = lat1; 
    lon2 = lon1; 

    while (lat2 > -37) { 
    lat2 = lat2 - 0.001; 
    var stest = "lat1=" + lat1 + ",lon1=" + lon1 + ",lat2=" + lat2 + ",lon2=" + lon2 + "=" + gc(lat1, lon1, lat2, lon2); 

    } 
    var d2 = new Date(); 
    var stest = (d2.getTime() - d1.getTime())/1000.0 + "s"; 
    $("#lblTest").html(stest + "<BR/>" + $("#lblTest").html()); 

} 
+0

哪個函數導致超時? – Zakaria

+0

嗨Zakaria我需要調用測試()模擬生產代碼中的錯誤,因爲它然後調用gc()高達1000次 – ajayel

回答

10

如果要執行的JavaScript長時間運行操作和你在任何地方接近一些瀏覽器執行腳本執行期限得到,那麼你將不得不打破你的功能分割成多個部分,運行一塊,到非常短的setTimeout(fn, 1),然後執行下一部分,等等......這樣做,您可以運行代碼幾個小時,因爲它使其他腳本和其他事件有機會處理。它有時需要少量的代碼重組才能做到這一點,但總是可以做一點工作。

僞碼的基本概念是這樣的:

var state = {}; // set initial state 
var done = false; 

function doWork() { 
    // do one increment of work that will never get even close to the browser 
    // execution time limit 
    // update the state object with our current operating state for the next execution 
    // set done = true when we're done processing 
    if (!done) { 
     setTimeout(doWork, 1); 
    } 
} 

doWork(); 

在特定的代碼,你可以做這樣的事情。您可以一次處理100個緯度點,然後執行一個簡短的setTimeout來執行下一個100點,依此類推。您可以將該數字調整爲最適合的數字。數字越高,每個計時器做的越多,整體執行時間越短,但越接近瀏覽器腳本執行限制。該setTimeout的保持瀏覽器活着(處理其他事件),並防止執行時間限制在踢。

function test() { 
    var d1 = new Date(); 
    var lat1, lon1, lat2, lon2, done = false;; 
    lat1 = -36; 
    lon1 = 174; 

    lat2 = lat1; 
    lon2 = lon1; 

    function calcGC() { 
     var cntr = 0; 
     while (lat2 > -37 && cntr < 100) { 
      lat2 = lat2 - 0.001; 
      var stest = "lat1=" + lat1 + ",lon1=" + lon1 + ",lat2=" + lat2 + ",lon2=" + lon2 + "=" + gc(lat1, lon1, lat2, lon2); 
      cntr++; 
     } 
     // if we have more to go, then call it again on a timeout 
     if (lat2 > -37) { 
      setTimeout(calcGC, 1); 
     } else { 
      var d2 = new Date(); 
      var stest = (d2.getTime() - d1.getTime())/1000.0 + "s"; 
      $("#lblTest").html(stest + "<BR/>" + $("#lblTest").html()); 
     } 
    } 
    calcGC(); 
} 
+0

非常感謝這個優秀的解釋和jfriend00例子,我們會盡快在我們的頁面上嘗試。精彩! – ajayel

+0

實施,效果非常好,再次感謝jfriend00 – ajayel

1

Apple的聲音減少了iOS5中JavaScript的執行超時。這可能是由於移動Safari中速度的普遍提升以及用於UIWebViews的Nitro引擎。

+0

肯定似乎是,我們的代碼在iOS4上運行良好並始終如一 – ajayel

4

我的感覺是,有在IOS5野生動物園中的錯誤,因爲一旦我開始得到這些錯誤,我得到他們的地方(包括谷歌手機搜索頁面),沒有可見的超時/暫停發生。殺死Safari瀏覽器並重新啓動它可以解決問題(直到它再次發生 - 也許是一個真正的超時,最初使Safari進入破壞狀態)。

您是否嘗試過通過多任務菜單殺死Safari瀏覽器並重新啓動呢?

0

我也認爲這是一個IOS5瀏覽器的bug。我們有類似的問題。我們有一個大型的RIA應用程序,它有很多Javascript代碼,在頁面刷新後,瀏覽器開始拋出超時異常。 iOS4沒有這個問題。一旦異常開始發生,情況就會惡化,直到瀏覽器完全崩潰:其他不相關的頁面拋出異常並拒絕呈現。

殺Safari瀏覽器並重新啓動它使問題消失。

+0

喜VladH和威爾院長,我們的錯誤可能是一致的,甚至新鮮的瀏覽器複製和已經與jfriend00s做法完全消失。雖然有趣的是,如果兩個瀏覽器(或全屏網頁)窗口同時運行相同的代碼,我們會得到原始問題中描述的javascript錯誤。 – ajayel

+0

@VladH,你在你的應用中使用window.setTimeout或window.setInterval嗎? – illvm

+0

不,我們仍在試圖確定應用程序中究竟是導致超時的部分 - 我們的應用程序非常龐大且高度異步。然而,即使我們設法找到解決辦法,也存在一個更大的問題:一旦這些超時錯誤開始彈出,Safari就會中斷 - 一次刷新頁面幾次,現在JS腳本沒有問題,甚至停止工作不相關的網站在不同的標籤中。我們的腳本不應該能夠打破瀏覽器。順便說一句,我們剛剛在谷歌地圖網站上通過切換衛星層來重現這一點。 – VladH