Apakah ada cara untuk memanggil fungsi secara berkala di JavaScript?

128

Apakah ada cara untuk memanggil fungsi secara berkala di JavaScript?

coderex
sumber

Jawaban:

214

Anda ingin setInterval():

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

Parameter pertama ke setInterval () juga bisa berupa serangkaian kode yang akan dievaluasi.

Anda dapat menghapus fungsi periodik dengan:

clearInterval(intervalID);
zombat
sumber
15
Saya terbalik dan kemudian memutuskan untuk membatalkan upvote saya (tetapi tidak downvote) karena Anda menggunakan argumen string ke setInterval. Fungsi hampir selalu harus digunakan untuk argumen string, untuk efisiensi, keamanan, dan untuk fitur penutupannya.
Jason S
5
Tidak apa-apa, saya tidak keberatan. setInterval()adalah jawaban yang benar untuk pertanyaan itu, apa pun parameternya. Ini hanyalah sebuah contoh, dan kedua metode tersebut menurut definisi benar.
zombat
2
Saya setuju dengan Jason S; itu harus benar-benar berfungsi. Dalam contoh Anda, satu-satunya masalah adalah kehilangan kinerja yang dapat diabaikan, tetapi kebiasaan buruk untuk melakukannya.
Matthew Crumley
4
Saya setuju dengan Anda berdua, menggunakan fungsi lebih baik. Saya tidak pernah mengatakan itu tidak benar. Cara itu benar, tetapi demi komentar, saya akan mengedit jawaban yang berisi fungsi sebagai gantinya.
zombat
37

Harap perhatikan bahwa setInterval () seringkali bukan solusi terbaik untuk eksekusi berkala - Ini sangat tergantung pada javascript apa yang sebenarnya Anda panggil secara berkala.

misalnya. Jika Anda menggunakan setInterval () dengan periode 1000ms dan dalam fungsi periodik Anda membuat panggilan ajax yang kadang-kadang membutuhkan waktu 2 detik untuk kembali, Anda akan membuat panggilan ajax lain sebelum respons pertama kembali. Ini biasanya tidak diinginkan.

Banyak perpustakaan memiliki metode periodik yang melindungi dari jebakan menggunakan setInterval secara naif seperti contoh Prototipe yang diberikan oleh Nelson.

Untuk mencapai eksekusi periodik yang lebih kuat dengan fungsi yang memiliki panggilan ajax jQuery, pertimbangkan sesuatu seperti ini:

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);

Pendekatan lain adalah dengan menggunakan setTimeout tetapi lacak waktu yang telah berlalu dalam suatu variabel dan kemudian atur waktu tunda setiap doa secara dinamis untuk menjalankan fungsi sedekat mungkin dengan interval yang diinginkan tetapi tidak pernah lebih cepat daripada Anda bisa mendapatkan respons kembali.

Matt Coubrough
sumber
setTimeout (myPeriodicMethod, 1000); disebut 2 kali. apakah itu diperlukan? Saya pikir waktu yang ditetapkan harus dipanggil hanya dalam fungsi lengkap
Vishnudev K
1
Ya setTimeout kedua () bukan keharusan, Anda cukup memanggil myPeriodicMethod () yang akan segera melakukan panggilan ajax pertama ... tetapi jika Anda ingin menjadwalkannya dengan penundaan dari panggilan pertama, Anda dapat menuliskannya sebagai Saya telah menulis.
Matt Coubrough
16

Setiap orang sudah memiliki solusi setTimeout / setInterval. Saya pikir penting untuk dicatat bahwa Anda dapat melewatkan fungsi ke setInterval, bukan hanya string. Ini sebenarnya mungkin sedikit "lebih aman" untuk melewati fungsi nyata daripada string yang akan "ditingkatkan" ke fungsi tersebut.

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

Atau:

// example 2
var counter = 0;
var interval = setInterval(function() { alert("#"+counter++); }, 5000);
gnarf
sumber
3
+1 Jika Anda seorang siswa sekolah JavaScript Crockford , Anda menghindari eval dalam semua bentuk kejahatannya.
Patrick McElhaney
@ Patrick - Saya tidak berpikir saran "Jangan gunakan $ (tanda dolar) atau \ (backslash) dalam nama" akan turun dengan baik dengan lot jQuery :)
Russ Cam
6

Pertanyaan lama tapi .. Saya juga membutuhkan pelari tugas berkala dan menulis TaskTimer . Ini juga berguna ketika Anda perlu menjalankan banyak tugas pada interval yang berbeda.

// 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();

TaskTimerberfungsi baik di browser dan Node. Lihat dokumentasi untuk semua fitur.

Onur Yıldırım
sumber
3

ya - lihat setIntervaldansetTimeout untuk mengeksekusi kode pada waktu-waktu tertentu. setInterval akan menjadi yang digunakan untuk mengeksekusi kode secara berkala.

Lihat demo dan jawab di sini untuk penggunaan

Russ Cam
sumber
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);
}
Ben Lesh
sumber
1

Karena Anda ingin fungsi dijalankan secara berkala , gunakan setInterval

CMS
sumber
1

Cara asli memang setInterval()/ clearInterval(), tetapi jika Anda sudah menggunakan perpustakaan Prototipe Anda dapat memanfaatkan PeriodicalExecutor:

new PeriodicalUpdator(myEvent, seconds);

Ini mencegah panggilan yang tumpang tindih. Dari http://www.prototypejs.org/api/ PeriodicalExecuter :

"Ini melindungi Anda terhadap beberapa eksekusi paralel dari fungsi callback, jika diperlukan lebih lama dari interval yang diberikan untuk mengeksekusi (itu mempertahankan bendera" berjalan "internal, yang dilindungi terhadap pengecualian dalam fungsi callback). Ini sangat berguna jika Anda gunakan satu untuk berinteraksi dengan pengguna pada interval tertentu (mis. gunakan permintaan atau konfirmasi panggilan): ini akan menghindari beberapa kotak pesan yang semuanya menunggu untuk ditindaklanjuti. "

Nelson
sumber