Có cách nào để gọi một hàm định kỳ trong JavaScript không?


Câu trả lời:


214

Bạn muốn setInterval():

var intervalID = setInterval(function(){alert("Interval reached");}, 5000);

Tham số đầu tiên cho setInterval () cũng có thể là một chuỗi mã được ước tính.

Bạn có thể xóa một chức năng định kỳ với:

clearInterval(intervalID);

15
Tôi upvote và sau đó quyết định hủy bỏ upvote của tôi (nhưng không downvote) bởi vì bạn đang sử dụng một đối số chuỗi để setInterval. Các hàm hầu như luôn luôn được sử dụng theo hướng đối số chuỗi, vì tính hiệu quả, bảo mật và cho các tính năng đóng của chúng.
Jason S

5
Điều đó tốt, tôi không phiền. setInterval()là câu trả lời chính xác cho câu hỏi, bất kể tham số. Đây chỉ là một ví dụ và cả hai phương pháp đều đúng theo định nghĩa.
zombat

2
Tôi đồng ý với Jason S; nó thực sự nên là một chức năng Trong ví dụ của bạn, vấn đề duy nhất là mất hiệu suất không đáng kể, nhưng đó là một thói quen xấu cần phải làm.
Matthew Crumley

4
Tôi đồng ý với cả hai bạn, sử dụng một chức năng là tốt hơn. Tôi chưa bao giờ nói nó không phải. Đó là một trong hai cách chính xác, nhưng vì lợi ích của các bình luận, tôi sẽ chỉnh sửa câu trả lời để chứa một chức năng thay thế.
zombat

37

Xin lưu ý rằng setInterval () thường không phải là giải pháp tốt nhất để thực hiện định kỳ - Nó thực sự phụ thuộc vào javascript mà bạn thực sự gọi theo định kỳ.

ví dụ. Nếu bạn sử dụng setInterval () với khoảng thời gian 1000ms và trong hàm tuần hoàn, bạn thực hiện cuộc gọi ajax mà thỉnh thoảng mất 2 giây để trả về, bạn sẽ thực hiện một cuộc gọi ajax khác trước khi phản hồi đầu tiên trở lại. Điều này thường là không mong muốn.

Nhiều thư viện có các phương pháp định kỳ bảo vệ chống lại những cạm bẫy của việc sử dụng setInterval một cách ngây thơ, chẳng hạn như ví dụ Prototype được đưa ra bởi Nelson.

Để đạt được sự thực thi định kỳ mạnh mẽ hơn với một hàm có lệnh gọi ajax jQuery trong đó, hãy xem xét một cái gì đó như thế này:

function myPeriodicMethod() {
  $.ajax({
    url: ..., 
    success: function(data) {
      ...
    },
    complete: function() {
      // schedule the next request *only* when the current one is complete:
      setTimeout(myPeriodicMethod, 1000);
    }
  });
}

// schedule the first invocation:
setTimeout(myPeriodicMethod, 1000);

Một cách tiếp cận khác là sử dụng setTimeout nhưng theo dõi thời gian đã trôi qua trong một biến và sau đó thiết lập độ trễ thời gian chờ trên mỗi lệnh gọi để thực thi một hàm càng gần khoảng thời gian mong muốn càng tốt nhưng không bao giờ nhanh hơn bạn có thể nhận được phản hồi.


setTimeout (myPeriodicMethod, 1000); được gọi là 2 lần. nó có được yêu cầu không? Tôi nghĩ rằng thiết lập thời gian chờ chỉ nên được gọi trong chức năng hoàn chỉnh
Vishnudev K

1
Có, setTimeout () thứ hai không phải là một yêu cầu, bạn chỉ cần gọi myPeriodicMethod () sẽ thực hiện cuộc gọi ajax đầu tiên ngay lập tức ... nhưng nếu bạn muốn lên lịch với sự chậm trễ từ cuộc gọi đầu tiên, bạn có thể viết nó dưới dạng Tôi đã viết.
Matt Coubrough

16

Mọi người đều có giải pháp setTimeout / setInterval rồi. Tôi nghĩ rằng điều quan trọng cần lưu ý là bạn có thể truyền các hàm cho setInterval, không chỉ các chuỗi. Nó thực sự có thể "an toàn" hơn một chút để vượt qua các hàm thực thay vì các chuỗi sẽ được "đánh giá" cho các hàm đó.

// example 1
function test() {
  alert('called');
}
var interval = setInterval(test, 10000);

Hoặc là:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);

3
+1 Nếu bạn là học sinh của trường JavaScript Crockford , bạn sẽ tránh được mọi hình thức xấu xa.
Patrick McElhaney

@Patrick - Tôi không nghĩ rằng đề xuất "Không sử dụng $ (ký hiệu đô la) hoặc \ (dấu gạch chéo ngược) trong tên" sẽ đi xuống tốt với lô jQuery :)
Russ Cam

6

Câu hỏi cũ nhưng .. Tôi cũng cần một người chạy nhiệm vụ định kỳ và viết TaskTimer . Điều này cũng hữu ích khi bạn cần chạy nhiều tác vụ trên các khoảng thời gian khác nhau.

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

// Add task(s) based on tick intervals.
timer.addTask({
    name: 'job1',       // unique name of the task
    tickInterval: 5,    // run every 5 ticks (5 x interval = 5000 ms)
    totalRuns: 10,      // run 10 times only. (set to 0 for unlimited times)
    callback: function (task) {
        // code to be executed on each run
        console.log(task.name + ' task has run ' + task.currentRuns + ' times.');
    }
});

// Start the timer
timer.start();

TaskTimerhoạt động cả trong trình duyệt và Node. Xem tài liệu cho tất cả các tính năng.




2
function test() {
 alert('called!');
}
var id = setInterval('test();', 10000); //call test every 10 seconds.
function stop() { // call this to stop your interval.
   clearInterval(id);
}


1

Cách gốc thực sự là setInterval()/ clearInterval(), nhưng nếu bạn đã sử dụng thư viện Prototype, bạn có thể tận dụng periodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Điều này ngăn chặn các cuộc gọi chồng chéo. Từ http://www.prototypejs.org/api/ periodicalExecuter :

"nó bảo vệ bạn chống lại nhiều lần thực thi song song của chức năng gọi lại, nên mất nhiều thời gian hơn khoảng thời gian đã cho để thực thi (nó duy trì một cờ chạy nội bộ, được bảo vệ chống lại các ngoại lệ trong chức năng gọi lại). Điều này đặc biệt hữu ích nếu bạn sử dụng một để tương tác với người dùng theo các khoảng thời gian nhất định (ví dụ: sử dụng lời nhắc hoặc xác nhận cuộc gọi): điều này sẽ tránh được nhiều hộp thông báo tất cả đang chờ để được xử lý. "

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.