Jawaban:
Ini paling sederhana untuk langsung memanggil fungsi itu sendiri secara langsung:
foo();
setInterval(foo, delay);
Namun ada alasan yang baik untuk dihindari setInterval
- khususnya dalam beberapa keadaan, seluruh setInterval
peristiwa dapat tiba setelah satu sama lain tanpa penundaan. Alasan lain adalah bahwa jika Anda ingin menghentikan loop Anda harus secara eksplisit memanggil clearInterval
yang berarti Anda harus mengingat pegangan yang dikembalikan dari setInterval
panggilan asli .
Jadi metode alternatif adalah foo
memicu sendiri untuk panggilan berikutnya menggunakan setTimeout
sebagai gantinya:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Ini menjamin bahwa setidaknya ada interval di delay
antara panggilan. Ini juga membuatnya lebih mudah untuk membatalkan loop jika diperlukan - Anda hanya tidak menelepon setTimeout
ketika kondisi terminasi loop Anda tercapai.
Lebih baik lagi, Anda bisa membungkus semuanya dalam ekspresi fungsi yang dipanggil langsung yang menciptakan fungsi, yang kemudian memanggil dirinya lagi seperti di atas, dan secara otomatis memulai loop:
(function foo() {
...
setTimeout(foo, delay);
})();
yang mendefinisikan fungsi dan memulai siklus semuanya sekaligus.
setTimeout
?
setInterval
acara dapat tiba segera setelah satu sama lain tanpa penundaan.
setTimeout
metode ini?
Saya tidak yakin apakah saya memahami Anda dengan benar, tetapi Anda dapat dengan mudah melakukan sesuatu seperti ini:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Jelas ada sejumlah cara untuk melakukan ini, tapi itu cara paling ringkas yang bisa saya pikirkan.
arguments.callee
tidak tersedia dalam mode ketat ES5
Saya menemukan pertanyaan ini karena masalah yang sama tetapi tidak ada jawaban yang membantu jika Anda perlu berperilaku persis seperti setInterval()
tetapi dengan satu - satunya perbedaan fungsi dipanggil segera di awal.
Ini solusi saya untuk masalah ini:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
Keuntungan dari solusi ini:
setInterval
dapat dengan mudah diadaptasi oleh substitusiclearInterval()
nantiContoh:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Untuk menjadi kurang ajar, jika Anda benar-benar perlu menggunakan setInterval
maka Anda juga bisa mengganti yang asli setInterval
. Karenanya, tidak diperlukan perubahan kode saat menambahkan ini sebelum kode yang ada:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Namun, semua keuntungan sebagaimana tercantum di atas berlaku di sini, tetapi tidak diperlukan penggantian.
setTimeout
solusi karena mengembalikan setInterval
objek. Untuk menghindari fungsi panggilan yang mungkin kemudian dalam kode dan karena itu tidak terdefinisi pada waktu saat ini, saya bungkus panggilan fungsi pertama dalam setTimeout
fungsi seperti ini: setTimeout(function(){ func();},0);
Fungsi pertama kemudian dipanggil setelah siklus pemrosesan saat ini, yang juga segera , tetapi lebih banyak kesalahan terbukti.
Anda bisa membungkus setInterval()
fungsi yang menyediakan perilaku itu:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... lalu gunakan seperti ini:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
Ini adalah pembungkus untuk cantik-cantik jika Anda membutuhkannya:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
Setel argumen ketiga setInterval ke true dan itu akan berjalan untuk pertama kalinya segera setelah memanggil setInterval:
setInterval(function() { console.log("hello world"); }, 5000, true);
Atau hilangkan argumen ketiga dan itu akan mempertahankan perilaku aslinya:
setInterval(function() { console.log("hello world"); }, 5000);
Beberapa browser mendukung argumen tambahan untuk setInterval yang tidak diperhitungkan oleh wrapper ini; Saya pikir ini jarang digunakan, tetapi ingatlah itu jika Anda memang membutuhkannya.
Untuk seseorang perlu membawa bagian luar this
seolah-olah itu adalah fungsi panah.
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Jika sampah yang dihasilkan di atas mengganggu Anda, Anda dapat melakukan penutupan.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Atau mungkin mempertimbangkan menggunakan yang @autobind
dekorator tergantung pada kode Anda.
Saya akan menyarankan memanggil fungsi dalam urutan berikut
var _timer = setInterval(foo, delay, params);
foo(params)
Anda juga dapat meneruskannya _timer
ke foo, jika Anda ingin clearInterval(_timer)
pada kondisi tertentu
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
Ini adalah versi sederhana untuk pemula tanpa semua masalah. Itu hanya menyatakan fungsi, memanggilnya, lalu memulai interval. Itu dia.
//Declare your function here
function My_Function(){
console.log("foo");
}
//Call the function first
My_Function();
//Set the interval
var interval = window.setInterval( My_Function, 500 );
Ada paket npm yang mudah disebut firstInterval (pengungkapan penuh, ini milik saya).
Banyak contoh di sini tidak termasuk penanganan parameter, dan mengubah perilaku default setInterval
dalam setiap proyek besar adalah kejahatan. Dari dokumen:
Pola ini
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
identik dengan
firstInterval(callback, 1000, p1, p2);
Jika Anda jadul di peramban dan tidak menginginkan ketergantungan, ini adalah cara mudah dan tempel dari kode.
// YCombinator
function anonymous(fnc) {
return function() {
fnc.apply(fnc, arguments);
return fnc;
}
}
// Invoking the first time:
setInterval(anonymous(function() {
console.log("bar");
})(), 4000);
// Not invoking the first time:
setInterval(anonymous(function() {
console.log("foo");
}), 4000);
// Or simple:
setInterval(function() {
console.log("baz");
}, 4000);
Ok ini sangat kompleks, jadi, izinkan saya menjelaskannya lebih sederhana:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Anda dapat mengatur waktu tunda awal yang sangat kecil (mis. 100) dan mengaturnya ke waktu tunda yang Anda inginkan dalam fungsi:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Ada masalah dengan panggilan asinkron langsung dari fungsi Anda, karena setTimeout / setInterval standar memiliki batas waktu minimal sekitar beberapa milidetik bahkan jika Anda langsung menetapkannya ke 0. Ini disebabkan oleh pekerjaan khusus browser.
Contoh kode dengan penundaan nol NYATA yang berfungsi di Chrome, Safari, Opera
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Anda dapat menemukan informasi lebih lanjut di sini
Dan setelah panggilan manual pertama Anda dapat membuat interval dengan fungsi Anda.
sebenarnya yang tercepat untuk dilakukan
interval = setInterval(myFunction(),45000)
ini akan memanggil fungsi saya, dan kemudian akan melakukannya setiap 45 detik yang berbeda dari melakukan
interval = setInterval(myfunction, 45000)
yang tidak akan menyebutnya, tapi jadwalkan saja
myFunction()
mengembalikan sendiri. Alih-alih memodifikasi setiap fungsi untuk dipanggil oleh setInterval
itu adalah pendekatan yang lebih baik untuk membungkus setInterval
sekali seperti yang diusulkan jawaban lainnya.
function
sekali dan kemudian melakukansetInterval()