2011-09-14 28 views
19

Her 20 saniyede bir işlevi çağırmak için setInterval() işlevini kullanıyorum. Ancak, fark ettiğim bir şey, ilk kez setInterval()'un aslında işlevinin 20 saniyede çağrılmasıdır (setInterval() çağrıldığında değil). İşte benim şu anki çözümüm:JavaScript: setInterval() şimdi nasıl başlamalı?

dothis(); 
var i = setInterval(dothis, 20000); 

Bu yinelenen kodu almadan bunu başarmanın herhangi bir yolu var mı?

cevap

29

Sizin yönteminiz bunu yapmanın normal yoludur. Bu defalarca gelirse

, önce işleyicisi yürütmek ve sonra aralığını teşkil edeceği bir yardımcı işlev yapabilir: Sonra

function setIntervalAndExecute(fn, t) { 
    fn(); 
    return(setInterval(fn, t)); 
} 

, kodunuzda, sadece bu yapabilirdi:

var i = setIntervalAndExecute(dothis, 20000); 
+0

Yararlı bilgi. Teşekkürler! – Andrew

2

dothis işlevinizde başka bir dönüş değeri yoksa, geri dönebilir.

Bu, aynı anda onu çağırmanıza ve iletmenize izin verir. Dönüş değeri aksi göz ardı edilirse, zararsız olacaktır.

DEMO:http://jsfiddle.net/ZXeUz/

Function.prototype.invoke_assign = function() { 
    var func = this, 
     args = arguments; 
    func.call.apply(func, arguments); 
    return function() { func.call.apply(func, args); }; 
}; 

setInterval(dothis.invoke_assign('thisArg', 1, 2, 3), 20000); 

// thisArg 1 2 3 
// thisArg 1 2 3 
// thisArg 1 2 3 
// ... 

Bu aslında artırır işleri biraz

function dothis() { 
    // your code 
    return dothis; 
} 

var i = setInterval(dothis(), 20000); 

Aksi takdirde, bir çağırma işlemi vermek ve tüm fonksiyonlara işlevselliğini geri dönmek için Function.prototype genişletmek olabilir . Bir dizi argümanı geçmene izin verir. İlk argüman, çağırmakta olduğunuz işlevin this değerini ayarlayacak ve argümanların geri kalanı normal argümanlar olarak iletilecektir.

Döndürülen işlev başka bir işleve sarıldığı için, ilk ve aralıklı çağrılar arasında aynı davranışa sahip olursunuz.

10

SetInterval yerine setTimeout işlevini kullanmanız dışında, anonim bir işlev gerçekleştirebilir ve hemen çağırabilirsiniz.

(function doStuff() { 
    //Do Stuff Here 
    setTimeout(doStuff,20000); 
})(); 

Bu, işlevi yürütecek, ardından 20 saniye içinde tekrar arayacaktır.

İstediğiniz davranışa veya bazı durumlarda performansa bağlı olarak setTimeout'u setInterval üzerinden kullanmak daha iyi olabilir. Asıl fark, setInterval'ın, zaman aşımı ne zaman olursa olsun bu fonksiyonu çağırmasıdır, son çağrı yürütülürse REGARDLESS veya bir hata oluşursa. SetTimeout'u kullanmak bu moda, zamanlayıcının sıfırlanmadan önce işlevinin yürütmeyi bitirmesini sağlar. Bir çok tradeoff çok açık, ancak uygulamanızı tasarlarken aklınızda bulundurmanız iyi bir şey.

EDIT Patrick dw'nin zaman aşımını iptal etme gereksinimiyle ilgili endişesine yanıt olarak.En iyi çözüm anonim işlevini kullanın ve sadece ilanı sonrasında diyoruz getirmemektir

var timeout; 
function doStuff() { 
    //doStuff 
    timeout = setTimeout(doStuff,20000); 
} 
doStuff() 

Evet bu OP önlemek çalışıyordu ne benzer, ancak çağrı sonra işlevini çağırmak ve ihtiyacını ortadan kaldırır gelmez setInterval işlevi, böylece bir kod satırı kaydedin. Fonksiyonu istediğiniz zaman durdurabilir ve başlatabilirsiniz:

//Stop it 
clearTimeout(timeout); 

//Start it 
doStuff(); 
+0

plus: "setTimeout", bir hata varsa tekrarlanmayacağından tercih edilir. – Hemlock

+0

+1 Bu işlevi dışsal olarak çağırmak için başka bir gereksinim yoksa, bunun iyi bir çözüm olduğunu düşünüyorum. – user113716

+0

... Şu anki cevabınız ile bir parça işlevsellik kaybediyor olmanıza rağmen. OP, 'setInterval' değişkeninin bir değişkene atanan dönüş sonucuna sahipti, bu da aralığın bir noktada iptal edilmesi anlamına gelebilir. Davranışı çoğaltmak için, çağırmayı durdurmak üzere ayarlanabilen bir bayrağın durumuna bağlı olan 'setTimeout' aracılığıyla yinelemeli aramayı yapmanız gerekir. – user113716

İlgili konular