2011-10-16 3 views
7

thử nghiệm sau đây về cơ bản là ~ 1000 hoạt động toán học và hoạt động tốt trên hầu hết các trình duyệt PC và Android và iOS 4.x. Trên safari iOS5 (iPhone 4 và iPad 2), chúng tôi nhận được "JavaScript: Lỗi thực thi JavaScript không xác định vượt quá thời gian chờ". Bất kỳ trợ giúp đánh giá cao cảm ơn.JavaScript IOS5 "JavaScript thực thi vượt quá thời gian chờ"

/** 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

Chức năng nào gây ra thời gian chờ? – Zakaria

+0

hi Zakaria i cần gọi test() mô phỏng lỗi trong mã sản xuất vì nó gọi gc() tối đa 1000 lần – ajayel

Trả lời

10

Nếu bạn muốn thực thi một hoạt động dài trong javascript và bạn nhận được bất kỳ nơi nào gần với thời gian thực thi tập lệnh được thực thi bởi một số trình duyệt, thì bạn sẽ phải phá vỡ chức năng của mình thành nhiều phần, chạy một phần, rất ngắn setTimeout(fn, 1) và sau đó thực thi đoạn tiếp theo, v.v ... Làm theo cách này, bạn có thể chạy mã trong nhiều giờ vì nó cung cấp cho các tập lệnh khác và các sự kiện khác một cơ hội để xử lý. Đôi khi nó đòi hỏi một số lượng nhỏ của tái cơ cấu mã để có thể làm điều này, nhưng nó luôn luôn có thể với một công việc nhỏ.

Các khái niệm cơ bản trong pseudo-code sẽ là:

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(); 

Trong mã cụ thể của bạn, bạn có thể làm một cái gì đó như thế này. Bạn có thể xử lý 100 điểm vĩ độ tại một thời điểm và sau đó thực hiện một setTimeout ngắn để thực hiện 100 bước tiếp theo và cứ tiếp tục như vậy. Bạn có thể điều chỉnh số 100 đó thành bất kỳ thứ gì sẽ hoạt động tốt nhất. Số càng cao, bạn càng thực hiện trên mỗi bộ hẹn giờ và thời gian thực thi tổng thể tốt hơn, nhưng bạn càng đạt được giới hạn thực thi tập lệnh trình duyệt. Các setTimeout giữ trình duyệt còn sống (xử lý các sự kiện khác) và ngăn chặn thời gian thực hiện hạn từ đá trong.

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

Rất cám ơn vì lời giải thích tuyệt vời này và ví dụ jfriend00, chúng tôi sẽ thử điều này trên trang của chúng tôi càng sớm càng tốt. Tuyệt vời! – ajayel

+0

được triển khai và hoạt động rất tốt nhờ jfriend00 một lần nữa – ajayel

1

Nghe như Apple đã giảm thời gian chờ thực hiện cho javascript trong iOS5. Điều này có thể là do những cải thiện tốc độ chung trong Mobile Safari và cũng bao gồm công cụ Nitro cho UIWebViews.

+0

chắc chắn là, mã của chúng tôi chạy tốt và nhất quán trên iOS4 – ajayel

4

Cảm giác của tôi là có một lỗi trong IOS5 safari, bởi vì một khi tôi đã bắt đầu để có được các lỗi này , Tôi nhận được tất cả các địa điểm (bao gồm cả trang tìm kiếm di động của Google), không có thời gian chờ/tạm dừng hiển thị. Giết Safari và khởi động lại nó sẽ khắc phục vấn đề (cho đến khi nó xảy ra lần nữa - có lẽ đó là một thời gian chờ chính hãng mà đặt Safari vào trạng thái bị hỏng ban đầu).

Bạn đã thử giết Safari thông qua menu đa nhiệm và khởi động lại trình duyệt chưa?

0

Tôi cũng nghĩ đó là lỗi trình duyệt IOS5. Chúng tôi có một vấn đề tương tự. Chúng tôi có một ứng dụng RIA lớn với nhiều mã Javascript, và sau khi làm mới trang trình duyệt bắt đầu ném các ngoại lệ thời gian chờ. iOS4 không có vấn đề này. Và một khi ngoại lệ bắt đầu xảy ra, nó đi từ xấu đến tồi tệ hơn, cho đến khi trình duyệt bị hỏng hoàn toàn: các trang không liên quan khác ném ngoại lệ và từ chối hiển thị.

Giết Safari và khởi động lại nó khiến cho sự cố không còn nữa.

+0

hi VladH và Will Dean, lỗi của chúng tôi có thể được sao chép liên tục ngay cả với trình duyệt mới và đã biến mất hoàn toàn với cách tiếp cận jfriend00s. Mặc dù thú vị nếu hai cửa sổ trình duyệt (hoặc toàn màn hình web) đang chạy cùng một mã tại cùng một thời điểm chúng tôi nhận được lỗi javascript được mô tả trong câu hỏi ban đầu. – ajayel

+0

@VladH, bạn có đang sử dụng window.setTimeout hoặc window.setInterval trong ứng dụng của mình không? – illvm

+0

Không, chúng tôi vẫn đang cố gắng xác định chính xác nơi ứng dụng của chúng tôi là phần gây ra thời gian chờ - ứng dụng của chúng tôi rộng lớn và không đồng bộ cao. Tuy nhiên, ngay cả khi chúng tôi quản lý để tìm một công việc xung quanh, có vấn đề lớn hơn: một khi những lỗi thời gian chờ bắt đầu bật lên, Safari bị hỏng - một lần làm mới trang một vài lần và bây giờ JS script không có vấn đề, ngừng làm việc ngay cả trên các trang web không liên quan trong các tab riêng biệt. Các tập lệnh của chúng tôi không thể phá vỡ trình duyệt. BTW, chúng tôi chỉ sao chép này trên trang web bản đồ google, bằng cách bật và tắt lớp vệ tinh. – VladH