2012-03-08 27 views
12

Tôi muốn bắt ngoại lệ được ném từ các cuộc gọi lại được chuyển đến jQuery (cho các trình xử lý sự kiện như click hoặc các phương thức jqXHR chẳng hạn như then hoặc always).Làm thế nào để bắt ngoại lệ được ném trong các cuộc gọi lại được chuyển tới jQuery?

tôi đã xác định được hai lựa chọn:

  • window.onerror handler - đây chỉ là một giải pháp phần vì nó không được hỗ trợ trên Android là một trong những nền tảng mục tiêu của tôi
  • ngoại lệ xử lý trong mỗi callback cá nhân - không hề chết!

Điều duy nhất tôi có thể nghĩ là ghi đè các phương thức jQuery nhưng điều đó có thể dẫn đến các sự cố bất kỳ lúc nào tôi nâng cấp jQuery. Đối với trình xử lý AJAX, tôi có thể sử dụng $ .ajaxSetup (mỗi câu trả lời cho Exceptions thrown in jQuery AJAX callbacks swallowed?) nhưng tôi không chắc chắn rằng sẽ cho phép tôi nắm bắt mọi thứ.

Có tùy chọn nào khác không?

Trả lời

15

Bạn có thể quấn mỗi callback như thế này:

function cbWrapper(fn) { 
    return function() { 
     try { 
      return(fn.apply(this, arguments)); 
     } catch(e) { 
      // handle all your exceptions here 
     } 
    }; 
} 

Vì vậy, khi bạn đi để vượt qua một callback để cuộc gọi Ajax, thay vì đi qua gọi lại thực tế, bạn vượt qua cbWrapper(callback).

$.get(url, cbWrapper(myRealCallback)); 

Hoặc phiên bản mang tính chất nội tuyến sẽ là như thế này:

$.get(url, cbWrapper(function() { 
    // actual callback code here 
})); 

Một cách tiên tiến hơn để làm việc đó sẽ ghi đè lên $.get() với thực hiện của riêng bạn mà kết thúc tốt đẹp gọi lại tự động, nhưng mà được khôn lanh vì jQuery rất linh hoạt về những đối số nào thực sự được chuyển. Vì lý do đó và vì bạn phải ghi đè một đối số cụ thể để thực hiện công việc này, bạn sẽ phải sao chép tất cả mã phát hiện đối số của chúng để tìm ra đối số nào có mặt và tương ứng với tham số chức năng thực tế nào. Mã đó hơi lộn xộn một chút. Nó có thể thực hiện được và có thể sẽ không phá vỡ vì nếu jQuery phá vỡ nó, thì mã jQuery hiện tại sẽ bị phá vỡ, nhưng nó không phải là rất sạch sẽ.

Nếu đó là tất cả các mã của riêng bạn, bạn chỉ có thể làm cho phiên bản của riêng bạn $.get() mà không phải là quá linh hoạt với vị trí đối số và chuyển đổi tất cả các mã của bạn để sử dụng nó thay cho thực tế $.get():

jQuery.fn.myGet = function(url, fn) { 
    return(jQuery.get(url, cbWrapper(fn))); 
} 
Các vấn đề liên quan