2013-06-28 30 views
7

(Tôi đã xem xét tất cả các câu hỏi tương tự/câu trả lời nhưng không ai trong số họ giải quyết vấn đề của tôi.)Javascript clearTimeout không làm việc

Mã:

var timeoutHandle; 

function showLoader(show) { 
    if (show) { 
     $('.loader').html('Loading...'); 
     $('.loader').show(); 

     timeoutHandle = setTimeout(function() { 
      if ($('.loader').is(':visible')) { 
       $('.loader').html('Still loading...'); 
      } 
     }, 15000); 
    } 
    else { 
     $('.loader').hide(); 
     clearTimeout(timeoutHandle); 
    } 
} 

Chức năng AJAX đơn giản gọi showLoader(true) trước khi gọi sau đó kết quả là showLoader(false). Đôi khi tôi vẫn thấy thay đổi văn bản từ "Đang tải ..." thành "Vẫn đang tải ..." trước 15 giây, vì vậy, dường như chuỗi chủ đề vẫn đang chạy. Có điều gì sai với mã ở trên không? Hoặc có thể vấn đề là với các mã khác ..

chỉnh sửa: Tôi phải thêm rằng showLoader(true) có thể được gọi là một lần nữa (và một lần nữa) trước khi phản hồi từ máy chủ

+0

chức năng mà các cuộc gọi "showLoader" là gì? Tôi có thể xem mã đó không? –

Trả lời

14

Bạn nên thêm một tấm séc để xem nếu có đã là timeoutHandle trước khi tạo một hình mới.

thử điều này:

if(timeoutHandle){ 
    clearTimeout(timeoutHandle); 
    timeoutHandle = null; 
} 
timeoutHandle = setTimeout(function() { 
    if ($('.loader').is(':visible')) { 
     $('.loader').html('Still loading...'); 
    } 
}, 15000); 

và sau đó trong trường hợp khác thiết timeoutHandle null sau khi bạn rõ ràng nó như vậy:

clearTimeout(timeoutHandle); 
timeoutHandle = null; 

này sẽ loại bỏ nguy cơ bạn tạo timeouts đồng thời nếu showLoader(true) hàm được gọi nhiều lần.

+7

Không cần kiểm tra. Chỉ cần gọi 'clearTimeout' – Ian

3

Điều gì có thể xảy ra là bạn đang đặt nhiều cuộc gọi đến showLoader vì đây là chức năng toàn cầu mà bạn có thể truy cập từ mọi nơi, thông thường bạn không muốn điều đó.

tôi sẽ xem xét thay đổi nó vào một đơn nguyên thực hiện:

function create_loader(elem) { 
    var handle = null; 

    function show() { 
     elem.html('Loading...'); 
     elem.show(); 

     if (handle !== null) { 
      clearTimeout(handle); // clear the previous one 
     } 
     handle = setTimeout(function() { 
      elem.html('Still loading...'); 
     }, 15000); 
    } 

    return { 
     show: show, 
     clear: function() { 
      elem.hide(); 
      clearTimeout(handle); 
      handle = null; 
     } 
    }; 
} 

Cách sử dụng:

var loader = create_loader($(".loader")); 
loader.clear(); 
loader.show(); 
loader.show(); // each new call to show will reset the 15s timer 
loader.show(); 
loader.show(); 
loader.clear(); 
// and you can make another one that operates independently of other one 
var another_loader = create_loader($(".anotherLoader")); 

Bây giờ bạn có một đối tượng loader mà biết về trạng thái riêng của nó.

+0

Rất nhiều thông tin, cảm ơn bạn. Tuy nhiên, giải pháp của Omar dễ hiểu hơn đối với tôi. – user982119

+0

Giải pháp của Omar là tốt, tôi đi thêm một bước nữa. Tôi loại bỏ 'timeoutHandle' khỏi phạm vi toàn cục, và liên kết với một thể hiện của trình nạp. Bây giờ chỉ 'loader' nằm trong phạm vi toàn cục và nó giữ trạng thái riêng của nó. – Halcyon

+0

+1 để đóng gói id hẹn giờ.Bạn có thể thực hiện thêm một bước nữa và thêm gọi lại khi tải xong. –

1

Trong bài đăng của bạn, bạn đề cập đến trình tải hiển thị có thể được gọi nhiều lần trước lần trả lại đầu tiên. Đây là vấn đề của bạn. Bạn đang ghi đè lên một timeoutHandle đã tồn tại với một cái mới mà không phá hủy xử lý đã tồn tại. Bạn nên kiểm tra xem timeoutHandle đã được đặt hay chưa được thiết lập trước khi tạo một cái mới.

0

Bạn không gọi clearTimeout (timeoutHandle) sau đó bắt đầu yêu cầu mới, nếu timeoutHandle tồn tại

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