Dừng cuộc gọi setInterval trong JavaScript


1398

Tôi đang sử dụng setInterval(fname, 10000);để gọi một chức năng cứ sau 10 giây bằng JavaScript. Có thể ngừng gọi nó trên một số sự kiện?

Tôi muốn người dùng có thể dừng việc làm mới dữ liệu lặp đi lặp lại.

Câu trả lời:


2160

setInterval()trả về một ID khoảng thời gian mà bạn có thể chuyển đến clearInterval():

var refreshIntervalId = setInterval(fname, 10000);

/* later */
clearInterval(refreshIntervalId);

Xem các tài liệu cho setInterval()clearInterval().


42
Làm thế nào bạn có thể bắt đầu lại sau khi dừng với 'clearInterval ()'? Nếu tôi cố gắng khởi động lại, tôi nhận được gấp đôi số setInterval đang chạy.
Dan

8
Tôi cũng vậy Mỗi lần tôi muốn sử dụng SetInterval (MyFunction, 4000); nó trở nên nhanh hơn và nhanh hơn, mỗi lần nhanh hơn gấp 2 lần :( làm thế nào tôi có thể khởi động lại một setinterval ??
Alireza Masali

14
SetInterval () không thay đổi tốc độ mà bạn vượt qua. Nếu bất cứ điều gì nó đang tăng tốc mỗi lần bạn gọi SetInterval (), thì bạn có nhiều bộ định thời đang chạy cùng một lúc và sẽ mở một câu hỏi mới.
EpicVoyage

29
Hãy chắc chắn rằng bạn đang thực sự ngăn chặn nó. Do phạm vi biến đổi, bạn có thể không có Id đúng để gọi clearInterval. Tôi đã sử dụng window.refreshIntervalIdthay vì một biến cục bộ, và nó hoạt động rất tốt!
osa

2
Tôi đã bắt đầu gắn tay cầm setInterval vào phần tử liên quan của nó (khi có liên quan): $('foo').data('interval', setInterval(fn, 100));và sau đó xóa nó với clearInterval($('foo').data('interval'));tôi chắc chắn cũng có một cách không phải là jQuery để làm điều đó.
Michael - Clay Shirky ở đâu

105

Nếu bạn đặt giá trị trả về của setIntervalmột biến, bạn có thể sử dụng clearIntervalđể dừng nó.

var myTimer = setInterval(...);
clearInterval(myTimer);

Tôi không thấy sự khác biệt giữa câu trả lời này và câu trả lời của John
Bussyroopo

51

Bạn có thể đặt một biến mới và tăng nó lên bằng ++ (đếm một) mỗi khi nó chạy, sau đó tôi sử dụng một câu lệnh có điều kiện để kết thúc nó:

var intervalId = null;
var varCounter = 0;
var varName = function(){
     if(varCounter <= 10) {
          varCounter++;
          /* your code goes here */
     } else {
          clearInterval(intervalId);
     }
};

$(document).ready(function(){
     intervalId = setInterval(varName, 10000);
});

Tôi hy vọng rằng nó sẽ giúp và nó là đúng.


3
Tôi đã ngạc nhiên khi biết rằng điều này làm việc clearInterval(varName);. Tôi dự kiến ​​sẽ clearIntervalkhông hoạt động khi thông qua tên chức năng, tôi nghĩ rằng nó yêu cầu ID khoảng. Tôi cho rằng điều này chỉ có thể hoạt động nếu bạn có một hàm được đặt tên, vì bạn không thể truyền một hàm ẩn danh dưới dạng một biến trong chính nó.
Patrick M

31
Thật ra tôi nghĩ nó không hoạt động. Mã dừng được thực thi do hạn chế trên bộ đếm, nhưng khoảng thời gian tiếp tục bắn varName (). Hãy thử ghi lại bất cứ điều gì sau ClearInterval () (bên trong mệnh đề khác) và bạn sẽ thấy nó được viết mãi mãi.
Rafael Oliveira

5
Vì vậy, rất nhiều sự ủng hộ cho một cái gì đó không hoạt động, đôi khi tôi không hiểu mọi người trên SO: P
Bị mắc kẹt vào

2
$(document).ready(function(){ });là jQuery, đó là lý do tại sao nó không hoạt động. Điều này đã được đề cập ít nhất.
paddotk

4
@OMGrant, Ngoài một ví dụ không hoạt động, bạn có một biến có tên varName, lưu trữ một hàm không tên - wha ?? Bạn nên thay đổi hoặc gỡ xuống câu trả lời này, IMHO.
Dean Radcliffe

13

Các câu trả lời ở trên đã giải thích cách setInterval trả về một điều khiển và cách xử lý này được sử dụng để hủy bộ đếm thời gian Interval.

Một số cân nhắc về kiến ​​trúc:

Vui lòng không sử dụng các biến "không có phạm vi". Cách an toàn nhất là sử dụng thuộc tính của đối tượng DOM. Nơi dễ nhất sẽ là "tài liệu". Nếu quá trình làm mới được bắt đầu bằng nút start / stop, bạn có thể sử dụng chính nút đó:

<a onclick="start(this);">Start</a>

<script>
function start(d){
    if (d.interval){
        clearInterval(d.interval);
        d.innerHTML='Start';
    } else {
        d.interval=setInterval(function(){
          //refresh here
        },10000);
        d.innerHTML='Stop';
    }
}
</script>

Vì chức năng được xác định bên trong trình xử lý nhấp vào nút, bạn không phải xác định lại. Bộ hẹn giờ có thể được nối lại nếu nút được nhấp lại.


1
Điều gì tốt hơn về việc đưa nó vào documenthơn window?
icktoofay

1
điều chỉnh. Tôi có ý nói tài liệu. Mọi người. Trong ví dụ mã của tôi, tôi sử dụng nút này một cách hiệu quả. Không có ID cho nút, nhưng con trỏ "này" được liên kết với tham số "d" trong hàm. Sử dụng "cửa sổ" làm phạm vi là rủi ro vì các chức năng cũng có. Ví dụ: "function test () {}" có thể truy cập qua window.test, tương tự như không sử dụng phạm vi nào cả, vì đó là một tốc ký. Hi vọng điêu nay co ich.
Schien

1
không mất các biến "scope-less" -> không sử dụng "scope-less" Tôi đã chỉnh sửa nó, nhưng thay đổi nhỏ hơn 6 chữ cái và lỗi gây nhầm lẫn.
Leif Neland

2
Bạn không cần DOM cho điều đó. Chỉ cần cho chúng tôi một IIFE để tránh ô nhiễm phạm vi toàn cầu.
Onur Yıldırım

1
Tôi phải thêm 'd.interval = không xác định' sau Internalhtml = 'start' để làm cho nó hoạt động trở lại. Bởi vì như thế chỉ hoạt động một lần.
jocmtb

11

Đã trả lời ... Nhưng nếu bạn cần một tính năng, tái sử dụng timer mà còn hỗ trợ nhiều tác vụ trên khoảng cách khác nhau, bạn có thể sử dụng của tôi TaskTimer (đối với Node và trình duyệt).

// Timer with 1000ms (1 second) base interval resolution.
const timer = new TaskTimer(1000);

// Add task(s) based on tick intervals.
timer.add({
    id: 'job1',         // unique id of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (omit for unlimited times)
    callback(task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
        // stop the timer anytime you like
        if (someCondition()) timer.stop();
        // or simply remove this task if you have others
        if (someCondition()) timer.remove(task.id);
    }
});

// Start the timer
timer.start();

Trong trường hợp của bạn, khi người dùng nhấp để làm phiền dữ liệu - làm mới; bạn cũng có thể gọi timer.pause()sau đó timer.resume()nếu họ cần kích hoạt lại.

Xem thêm tại đây .


6

Phương thức clearInterval () có thể được sử dụng để xóa bộ định thời gian với phương thức setInterval ().

setInterval luôn trả về giá trị ID. Giá trị này có thể được truyền vào ClearInterval () để dừng bộ hẹn giờ. Dưới đây là một ví dụ về bộ đếm thời gian bắt đầu từ 30 và dừng khi nó trở thành 0.

  let time = 30;
  const timeValue = setInterval((interval) => {
  time = this.time - 1;
  if (time <= 0) {
    clearInterval(timeValue);
  }
}, 1000);

5

@cnu,

Bạn có thể dừng khoảng thời gian, khi thử chạy mã trước khi xem trình duyệt bảng điều khiển của bạn (F12) ... hãy thử nhận xét ClearInterval (trình kích hoạt) là tìm lại giao diện điều khiển, không phải trình làm đẹp? : P

Kiểm tra ví dụ một nguồn:

var trigger = setInterval(function() { 
  if (document.getElementById('sandroalvares') != null) {
    document.write('<div id="sandroalvares" style="background: yellow; width:200px;">SandroAlvares</div>');
    clearInterval(trigger);
    console.log('Success');
  } else {
    console.log('Trigger!!');
  }
}, 1000);
<div id="sandroalvares" style="background: gold; width:200px;">Author</div>


3

Khai báo biến để gán giá trị được trả về từ setInterval (...) và chuyển biến được gán cho clearInterval ();

ví dụ

var timer, intervalInSec = 2;

timer = setInterval(func, intervalInSec*1000, 30 ); // third parameter is argument to called function 'func'

function func(param){
   console.log(param);
}

// Bất cứ nơi nào bạn truy cập vào bộ đếm thời gian được khai báo ở trên, hãy gọi ClearInterval

$('.htmlelement').click( function(){  // any event you want

       clearInterval(timer);// Stops or does the work
});

1
var keepGoing = true;
setInterval(function () {
     if (keepGoing) {
        //DO YOUR STUFF HERE            
        console.log(i);
     }
     //YOU CAN CHANGE 'keepGoing' HERE
  }, 500);

Bạn cũng có thể dừng khoảng thời gian bằng cách thêm một trình lắng nghe sự kiện để giả sử một nút có ID "stop-distance":

$('buuton#stop-interval').click(function(){
   keepGoing = false;
});

HTML:

<button id="stop-interval">Stop Interval</button>

Lưu ý: Khoảng thời gian sẽ vẫn được thực hiện, mặc dù không có gì sẽ xảy ra.


2
Điều này thực sự trở lại cho hiệu suất và đối với các tab nền, nó thực sự sẽ làm chậm tất cả các bộ định thời khác rất nhiều vì các bộ định thời và khoảng thời gian được điều chỉnh cho các tab nền
Ferrybig

1

Đây là cách tôi sử dụng phương thức clearInterval () để dừng bộ hẹn giờ sau 10 giây.

function startCountDown() {
  var countdownNumberEl = document.getElementById('countdown-number');
  var countdown = 10;
  const interval = setInterval(() => {
    countdown = --countdown <= 0 ? 10 : countdown;
    countdownNumberEl.textContent = countdown;
    if (countdown == 1) {
      clearInterval(interval);
    }
  }, 1000)
}
<head>
  <body>
    <button id="countdown-number" onclick="startCountDown();">Show Time </button>
  </body>
</head>


1

Sử dụng setTimeOut để dừng khoảng thời gian sau một thời gian.

var interVal = setInterval(function(){console.log("Running")  }, 1000);
 setTimeout(function (argument) {
    clearInterval(interVal);
 },10000);

0

Tôi đoán đoạn mã sau sẽ giúp:

var refreshIntervalId = setInterval(fname, 10000);

clearInterval(refreshIntervalId);

Bạn đã làm đúng mã 100% ... Vậy ... Có vấn đề gì vậy? Hoặc đó là một hướng dẫn ...


-3

Tại sao không sử dụng một cách tiếp cận đơn giản hơn? Thêm một lớp học!

Đơn giản chỉ cần thêm một lớp cho biết khoảng thời gian không làm gì cả. Ví dụ: trên di chuột.

var i = 0;
this.setInterval(function() {
  if(!$('#counter').hasClass('pauseInterval')) { //only run if it hasn't got this class 'pauseInterval'
    console.log('Counting...');
    $('#counter').html(i++); //just for explaining and showing
  } else {
    console.log('Stopped counting');
  }
}, 500);

/* In this example, I'm adding a class on mouseover and remove it again on mouseleave. You can of course do pretty much whatever you like */
$('#counter').hover(function() { //mouse enter
    $(this).addClass('pauseInterval');
  },function() { //mouse leave
    $(this).removeClass('pauseInterval');
  }
);

/* Other example */
$('#pauseInterval').click(function() {
  $('#counter').toggleClass('pauseInterval');
});
body {
  background-color: #eee;
  font-family: Calibri, Arial, sans-serif;
}
#counter {
  width: 50%;
  background: #ddd;
  border: 2px solid #009afd;
  border-radius: 5px;
  padding: 5px;
  text-align: center;
  transition: .3s;
  margin: 0 auto;
}
#counter.pauseInterval {
  border-color: red;  
}
<!-- you'll need jQuery for this. If you really want a vanilla version, ask -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<p id="counter">&nbsp;</p>
<button id="pauseInterval">Pause</button></p>

Tôi đã tìm kiếm cách tiếp cận nhanh chóng và dễ dàng này từ lâu, vì vậy tôi sẽ đăng một số phiên bản để giới thiệu càng nhiều người càng tốt.


17
Có vẻ như tôi không thực sự đơn giản hơn ... Tôi cũng nghĩ rằng sẽ tốt hơn để loại bỏ các khoảng thời gian của bạn thay vì giữ các cuộc gọi đến các chức năng không làm gì cả.
Romain Braun

Tôi không đồng ý. this.setInterval(function() { if(!$('#counter').hasClass('pauseInterval')) { //do something } }, 500);là tất cả những gì bạn có cho mã. Hơn nữa, kiểm tra là điều đầu tiên bạn làm, vì vậy nó rất nhẹ khi được di chuột. Đó là những gì cái này dùng để: tạm thời tạm dừng một chức năng . Nếu bạn muốn chấm dứt nó vô thời hạn: tất nhiên bạn loại bỏ khoảng thời gian.
Aart den Braber

Số tiền này để bỏ phiếu và thường không được khuyến khích. Nó sẽ đánh thức CPU từ trạng thái năng lượng thấp chỉ để thực hiện kiểm tra vô dụng (có khả năng). Nó cũng trì hoãn phản hồi từ ngay lập tức đến từ 0 đến 500 ms trong ví dụ này.
Charlie

Tôi hoàn toàn không đồng ý với bạn, ngay cả khi tôi đã viết mã 2 năm trước. Dù sao thì quầy cũng phải ở đó, vì OP đã yêu cầu. Chắc chắn, nếu bạn đang sử dụng điều này để dừng bộ đếm sau khi nhấn nút, ví dụ, đây sẽ là một giải pháp tối ưu phụ, nhưng chỉ để tạm dừng khi di chuột, đây là một trong những giải pháp đơn giản nhất hiện có.
Aart den Braber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.