Yanıtlar:
İşlevi ilk kez doğrudan kendiniz aramak en basit yöntemdir:
foo();
setInterval(foo, delay);
Bununla birlikte, kaçınmak için iyi nedenler vardır setInterval
- özellikle bazı durumlarda bir sürü setInterval
olay gecikmeden birbiri ardına gelebilir. Başka bir neden, döngüyü durdurmak istiyorsanız, açıkça çağırmanız clearInterval
gerekir, bu da orijinal setInterval
çağrıdan döndürülen tanıtıcıyı hatırlamanız gerektiği anlamına gelir .
Bu nedenle alternatif bir yöntem, bunun yerine foo
sonraki aramalar için kendisini tetiklemektir setTimeout
:
function foo() {
// do stuff
// ...
// and schedule a repeat
setTimeout(foo, delay);
}
// start the cycle
foo();
Bu, aramalar arasında en az bir aralık olmasını garanti eder delay
. Ayrıca gerekirse döngüyü iptal etmeyi de kolaylaştırır - sadece setTimeout
döngü sonlandırma koşulunuza ulaşıldığında aramazsınız.
Daha da iyisi, tüm bunları hemen yukarıdaki gibi çağıran ve döngüyü otomatik olarak başlatan işlevi yaratan hemen çağrılan bir işlev ifadesine sarılabilir :
(function foo() {
...
setTimeout(foo, delay);
})();
Bu da işlevi tanımlar ve döngüyü tek seferde başlatır.
setTimeout
ediyorsun?
setInterval
olay birbiri ardına gecikmeden gelebilir.
setTimeout
Yöntemi kullanırsam işlevi nasıl durdurabilirim ?
Seni doğru anladığımdan emin değilim, ama böyle bir şeyi kolayca yapabilirsin:
setInterval(function hello() {
console.log('world');
return hello;
}(), 5000);
Açıkçası bunu yapmanın birçok yolu var, ama bu benim düşünebileceğim en kısa yol.
arguments.callee
, ES5 katı modda mevcut değildir
Aynı sorun nedeniyle bu soru üzerine tökezledim, ancak tam olarak gibi davranmanız gerekiyorsa, setInterval()
ancak işlevin hemen başında çağrıldığı tek farkla cevapların hiçbiri yardımcı olmaz .
İşte bu sorunun çözümü:
function setIntervalImmediately(func, interval) {
func();
return setInterval(func, interval);
}
Bu çözümün avantajı:
setInterval
ikame ile kolayca uyarlanabilirclearInterval()
daha sonra iletebilirsinizMisal:
// create 1 second interval with immediate execution
var myInterval = setIntervalImmediately( _ => {
console.log('hello');
}, 1000);
// clear interval after 4.5 seconds
setTimeout( _ => {
clearInterval(myInterval);
}, 4500);
Arsız olmak için, gerçekten kullanmanız gerekiyorsa setInterval
, orijinali de değiştirebilirsiniz setInterval
. Bu nedenle, mevcut kodunuzdan önce bunu eklerken herhangi bir kod değişikliği gerekmez:
var setIntervalOrig = setInterval;
setInterval = function(func, interval) {
func();
return setIntervalOrig(func, interval);
}
Yine de, yukarıda listelenen tüm avantajlar burada geçerlidir, ancak ikame gerekli değildir.
setTimeout
çünkü bir setInterval
nesne döndürür . Belki daha sonra kodda ve bu nedenle tanımlanmamış şimdiki zamanda olan fonksiyonları çağıran önlemek için, bir ilk işlev çağrısını sarın setTimeout
: Böyle fonksiyonu setTimeout(function(){ func();},0);
ilk fonksiyonu daha sonra da geçerli işlem döngüsü, sonra çağrılır hemen , ama daha fazla hata kanıtlandı.
Bu setInterval()
davranışı sağlayan bir işlevi kapatabilirsiniz:
function instantGratification( fn, delay ) {
fn();
setInterval( fn, delay );
}
... sonra şu şekilde kullanın:
instantGratification( function() {
console.log( 'invoked' );
}, 3000);
İhtiyacınız olursa oldukça güzelleştirmek için bir sarıcı:
(function() {
var originalSetInterval = window.setInterval;
window.setInterval = function(fn, delay, runImmediately) {
if(runImmediately) fn();
return originalSetInterval(fn, delay);
};
})();
SetInterval öğesinin üçüncü bağımsız değişkenini true olarak ayarlayın; setInterval çağrıldıktan hemen sonra ilk kez çalıştırılır:
setInterval(function() { console.log("hello world"); }, 5000, true);
Veya üçüncü argümanı atlayın ve orijinal davranışını koruyun:
setInterval(function() { console.log("hello world"); }, 5000);
Bazı tarayıcılar , bu sarmalayıcının dikkate almadığı setInterval için ek argümanları destekler ; Bunların nadiren kullanıldığını düşünüyorum, ancak ihtiyacınız varsa bunu aklınızda bulundurun.
Çünkü birisinin this
bir ok işlevi gibi dışını içeri getirmesi gerekir .
(function f() {
this.emit("...");
setTimeout(f.bind(this), 1000);
}).bind(this)();
Yukarıdaki çöp üretmek sizi rahatsız ediyorsa, bunun yerine bir kapatma yapabilirsiniz.
(that => {
(function f() {
that.emit("...");
setTimeout(f, 1000);
})();
})(this);
Ya da belki kullanmayı düşünün dekoratör kodunuzu bağlı.@autobind
Fonksiyonları aşağıdaki sırayla çağırmayı önereceğim
var _timer = setInterval(foo, delay, params);
foo(params)
Belirli bir koşulda _timer
istiyorsanız, foo'ya da geçebilirsiniz.clearInterval(_timer)
var _timer = setInterval(function() { foo(_timer, params) }, delay);
foo(_timer, params);
İşte tüm karışıklık olmadan acemiler için basit bir sürüm. Sadece işlevi bildirir, çağırır, sonra aralığı başlatır. Bu kadar.
//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 );
FirstInterval (tam açıklama, benim) adlı kullanışlı bir npm paketi var.
Buradaki örneklerin çoğu parametre işlemeyi içermez ve setInterval
herhangi bir büyük projedeki varsayılan davranışlarını değiştirmek kötüdür. Dokümanlardan:
Bu desen
setInterval(callback, 1000, p1, p2);
callback(p1, p2);
ile aynı
firstInterval(callback, 1000, p1, p2);
Tarayıcıda eski bir okul iseniz ve bağımlılığı istemiyorsanız , koddan kolayca kesip yapıştırın .
// 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);
Tamam, bu çok karmaşık, o yüzden daha basit ifade edeyim:
function hello(status ) {
console.log('world', ++status.count);
return status;
}
setInterval(hello, 5 * 1000, hello({ count: 0 }));
Çok küçük bir başlangıç gecikme süresi (örn. 100) ayarlayabilir ve fonksiyon içinde istediğiniz gecikme süresine ayarlayabilirsiniz:
var delay = 100;
function foo() {
console.log("Change initial delay-time to what you want.");
delay = 12000;
setTimeout(foo, delay);
}
Standart setTimeout / setInterval, doğrudan 0'a ayarlasanız bile birkaç milisaniye hakkında minimum bir zaman aşımına sahip olduğundan, işlevinizin hemen eşzamansız çağrılmasıyla ilgili bir sorun vardır.
Chrome, Safari, Opera'da çalışan GERÇEK sıfır gecikmeli kod örneği
function setZeroTimeout(callback) {
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage('');
}
Daha fazla bilgiyi burada bulabilirsiniz
Ve ilk manuel aramadan sonra işlevinizle bir aralık oluşturabilirsiniz.
aslında en hızlısı yapmak
interval = setInterval(myFunction(),45000)
bu benim işlevimi arayacak ve sonra her 45 saniyede bir agaian yapacak
interval = setInterval(myfunction, 45000)
ki bu onu çağırmaz, ama sadece planla
myFunction()
kendi kendine dönerse çalışır . Bunun yerine, çağrılacak her işlevi değiştirmek , diğer yanıtların önerdiği gibi bir kez setInterval
sarmak için daha iyi bir yaklaşımdır setInterval
.
function
kez aramayı deneyebilir ve daha sonrasetInterval()