2011-07-21 62 views
13

Giả sử tôi có một số dữ liệu mà tôi cần nhận được từ máy chủ khoảng 10 giây một lần. Tôi sẽ có một chức năng mà được các dữ liệu thông qua AJAX và sau đó gọi setTimeout để gọi chức năng này một lần nữa:Cuộc gọi hàm 'setTimeout' đệ quy có thể hủy diệt JS Engine không?

function GetData(){ 
    $.ajax({ 
     url: "data.json", 
     dataType: "json", 
     success: function(data){ 
     // do somthing with the data 

     setTimeout(GetData, 10000); 
     }, 
     error: function(){ 
     setTimeout(GetData, 10000); 
     } 
    }); 
} 

Nếu ai đó rời khỏi trang web mở cửa cả ngày, nó có thể nhận được hàng ngàn cuộc gọi hàm đệ quy.

Tôi không muốn sử dụng setInterval vì điều đó không tính đến độ trễ mạng tài khoản. Nếu mạng đang bận và phải mất 15 giây để xử lý yêu cầu, tôi không muốn hỏi lại lần nữa trước khi tôi hết thời gian chờ AJAX.

Cách tốt nhất để xử lý một hàm cần được gọi định kỳ là gì?

+0

Mỗi cuộc gọi tiếp theo tới GetData sẽ hoàn toàn độc lập với nhau. Sau khi bất kỳ hoạt động thực thi GetData nào được hoàn thành, ngữ cảnh của nó sẽ bị hủy và một bối cảnh mới được tạo khi bộ đếm thời gian hết hạn. –

+0

điều này có thể gây ra sự cố cho máy chủ trước JavaScript phía máy khách. như những người khác đã đề cập, bạn không có một vấn đề ngăn xếp cuộc gọi vì setTimeout cho phép hàm trả về và được loại bỏ khỏi ngăn xếp. Đệ quy về mặt thuật toán, nhưng không thực sự. – aepheus

+0

Câu hỏi này chính xác là những gì tôi đang nghiên cứu. Cảm ơn bạn đã mang nó đến đây. – shaosh

Trả lời

21

Không có đệ quy thực sự vì lệnh gọi hàm GetData bị trì hoãn và bối cảnh JavaScript bị hủy trong thời gian chờ đợi. Vì vậy, nó sẽ không sụp đổ động cơ JS.

Đối với mẫu mã của bạn, điều này về cơ bản là những gì sẽ xảy ra ở cấp cơ JS:

  1. Initialize JS cơ
  2. Tạo GetData chức năng bối cảnh
  3. Execute báo cáo GetData bao gồm "setTimeout"
  4. "setTimeOut" hướng dẫn công cụ JS gọi một hàm trong 10 giây
  5. Hủy ngữ cảnh hàm GetData
  6. Tại thời điểm này, về mặt sử dụng bộ nhớ, chúng ta quay lại bước 1. Sự khác biệt duy nhất là công cụ JS lưu trữ một tham chiếu đến một hàm và khi nào gọi nó (cho phép gọi dữ liệu này là "futureCall").
  7. Sau 10 giây, lặp lại từ bước 2. "futureCall" bị hủy.
+0

Việc triển khai này có phụ thuộc không? Hoặc là điều này trong spec của JavaScript? – Robert

+0

Có ghi chú trong thông số kỹ thuật cho biết "không bao giờ phá hủy một bối cảnh mà từ đó setTimeout đã được gọi là". Nó không phải là một đệ quy, do đó, không có lý do gì mà việc thực thi sẽ thất bại, ngay cả những lỗi được mã hóa. –

+0

Tôi vẫn gói đầu của tôi xung quanh này ... Vì vậy, nếu tôi giả định tất cả mọi thứ trong JS được chạy như là một xử lý sự kiện, sau đó setTimeout chỉ gây ra một sự kiện khác để được xử lý. Nó có stack/thread/process/memory/tất cả mọi thứ. – Robert

Các vấn đề liên quan