2009-12-11 34 views
14

Tôi đang phát triển JS được sử dụng trong một khung công tác web và thường được trộn lẫn với mã jQuery của các nhà phát triển khác (thường dễ bị lỗi). Thật không may lỗi trong jQuery của họ (tài liệu). Các khối đã chặn ngăn không cho tôi thực thi. Lấy mẫu đơn giản sau đây:Xử lý lỗi trong jQuery (tài liệu) .ready

<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     nosuchobject.fakemethod();  //intentionally cause major error 
    }); 
</script> 
<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     alert("Hello!");     //never executed 
    }); 
</script> 

Không phải khối thứ hai sẵn sàng thực hiện bất kể những gì đã xảy ra trước đó? Có một cách "an toàn" để chạy jQuery (tài liệu). Đã có mà sẽ chạy ngay cả trong trường hợp của các lỗi trước đó?

EDIT: Tôi không có quyền kiểm soát/khả năng hiển thị đối với các khối dễ bị lỗi do chúng được viết bởi các tác giả khác và được trộn lẫn tùy ý.

Trả lời

13

Tôi chưa thử mã này, nhưng nó cũng làm việc (ít nhất, ý tưởng nên anyway). Hãy chắc chắn rằng bạn bao gồm nó SAU jquery, nhưng TRƯỚC KHI bất kỳ kịch bản có khả năng lỗi. (Không cần thiết, xem nhận xét.)

var oldReady = jQuery.ready; 
jQuery.ready = function(){ 
    try{ 
    return oldReady.apply(this, arguments); 
    }catch(e){ 
    // handle e .... 
    } 
}; 
+0

Điều này dường như hoạt động khá tốt, bất kể nó đi trước hay sau các tập lệnh có khả năng lỗi. Tôi nghĩ rằng những gì tôi sẽ làm là di chuyển các nội dung của khối đã sẵn sàng của tôi (cảnh báo ("Hello!") Trong mẫu) để chỉ sau khi khối catch. Bằng cách đó, khối sẵn sàng của tôi có thể "nối thêm" chính nó vào cuối các khối sẵn sàng trước đó. – 3hough

+0

Giải pháp tuyệt vời. Chưa bao giờ nghĩ về điều đó. –

+0

Không chắc mình đang nghĩ gì, nhưng nó sẽ hoạt động bất kể nó ở đâu, miễn là nó ở trong thẻ và không ở trong một số sự kiện onload, vì chúng ta đang cướp phương thức sẵn sàng trước khi nó được gọi vào tải trọng dom. – jvenema

1

Bạn đã cố gắng gói các lệnh dễ bị lỗi trong khi thử ... bắt các dấu ngoặc?

$(function(){ 
    try { 
     noObject.noMethod(); 
    } catch (error) { 
     // handle error 
    } 
}); 

$(function(){ 
    try { 
     alert("Hello World"); 
    } catch (error) { 
     // handle error 
    } 
}); 

Để tránh nhầm lẫn tiềm năng, $(function(){ ... }); là chức năng giống như $(document).ready(function(){ ... });

+0

Vấn đề là tôi không có quyền kiểm soát/tầm nhìn qua các khối ném lỗi. Trong ví dụ trên, khối jQuery (tài liệu) đầu tiên đã đến từ mã của người khác. Vì vậy, không may mắn thay tôi không có một cách để gói chúng trong các khối try/catch. Đây là một phần của khuôn khổ web nơi plugin tùy ý có thể tải cùng nhau trong phần đầu của tài liệu. – 3hough

+2

Bạn nên đề cập đến trong câu hỏi của mình rằng bạn không có quyền truy cập vào mã của họ. – Sampson

-2

Bạn có thể tham khảo lại jQuery trước mỗi khối mã của bạn. Mã của bạn sau đó sẽ sử dụng thể hiện mới của thư viện và nó sẽ thực thi. Tôi đã thử nghiệm điều này trong Safari 4.0.3 trên OSX.

<html> 
<head> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script> 
    <script type="text/javascript"> 
     jQuery(document).ready(function() { 
            nosuchobject.fakemethod();       //intentionally cause major error 
        }); 
    </script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>  
    <script type="text/javascript"> 
        jQuery(document).ready(function() { 
            alert("Hello!");                 //executed! 
        }); 
    </script> 

</head> 
<body> 

<p>hello world</p> 

</body> 
</html> 
+0

Ý tưởng khủng khiếp ... điều này sẽ ít nhất buộc người dùng tải xuống thư viện hai lần và cũng có thể gây ra sự cố với các biến tĩnh và các đối tượng bị ghi đè. – jvenema

+0

Trình duyệt của người dùng chỉ tải xuống lại tệp từ xa khi bộ đệm ẩn được đặt vào vị trí.Trong ví dụ của tôi, trình duyệt đọc tham chiếu jQuery thứ hai từ bộ nhớ cache. Nó không phải là đẹp, nhưng nó giúp giải quyết vấn đề ban đầu. Về các vấn đề với các biến tĩnh và các đối tượng, bạn có ý nghĩa trong chính thư viện jQuery, hoặc các biến và các đối tượng tĩnh do người dùng định nghĩa không? Trong trường hợp ghi đè, jQuery tự bản đồ hóa. Trong ví dụ của tôi, khối thứ hai được viết chính xác sẽ tham chiếu đến cá thể mới của jQuery. Bạn có thể vui lòng giải thích về các vấn đề bạn đề cập không? Cảm ơn! – simeonwillbanks

+0

Ngay tại đầu jquery, bạn sẽ thấy điều này: jQuery.fn = jQuery.prototype = {...}. Vì các đối tượng đó không được mở rộng nhưng được khởi tạo, bất kỳ thứ gì thay đổi hoặc chạm vào các thuộc tính đó (và thực sự, bất kỳ thứ gì khác được đặt tĩnh ở cấp jquery) sẽ được chuyển vào thùng rác. Và ngay cả khi trình duyệt lưu cache js, trình duyệt vẫn sẽ phải phân tích cú pháp lại và tải lại tất cả các phần tử đã khai báo, làm giảm trải nghiệm người dùng (chưa kể nó có thể giới thiệu rò rỉ bộ nhớ vì không có bất kỳ phần nào bị xóa sự kiện). – jvenema

2

Để trả lời câu hỏi của bạn, cả hai ready khối được về cơ bản kết hợp thành một cho cách jQuery hoạt động:

<script type="text/javascript"> 
    jQuery(document).ready(function() { 
     nosuchobject.fakemethod();  //intentionally cause major error 
     alert("Hello!");     //never executed 
    }); 
</script> 

Vì vậy, đó là lý do tại sao nó không cảnh báo mỗi lỗi trên. Tôi không tin rằng có một cách để sửa lỗi này để làm cho mọi hoạt động ready chạy bất kể lỗi trước đây.

1

Đây là giải pháp, nó sẽ quấn bất kỳ chức năng gửi đến sẵn sàng với khối try-catch:

(function($){ 
    $.fn.oldReady = $.fn.ready; 
    $.fn.ready = function(fn){ 
     return $.fn.oldReady(function(){ try{ if(fn) fn.apply($,arguments); } catch(e){}}); 
    } 
})(jQuery); 
Các vấn đề liên quan