inicio mail me! sindicaci;ón

Archive for JavaScript

setTimeout’un Recursive Kullanımında Farkettiğim Ayrıntı – setInverval ile Arasındaki Fark

Javascript’in bu iki timer fonksiyonu(setTimeout, setInterval) hakkında çok temel bilgiler vermeyeceğim, zira tekerleği tekrar tekrar anlatmaya gerek yok. En azından bu konudan farklı birşeyler öğrenerek ayrılmanızı diliyorum.

Javascript’in yalnızca tek thread‘de çalıştığını hatırlatarak, asenkron olaylar bir kuyruğa atılarak tek tek çalıştırılır. Yani gerçek manada aynı anda iki iş yapılamaz. Örneğin ilk iş bitmeden ikinci işe geçmek istemiyorsanız, setInterval tercihi çok doğru olmayacaktır. Zira setInterval ile belirlediğiniz süre içerisinde mevcut iş bitmemiş olabilir, ama bu durum gözardı edilir ve ikinci işe çoktan başlanmış olunur. Böylesi bir senaryo setTimeout recursive kullanılarak aşılabilir. Ancak bu da beklediğiniz aralıklarla işi gerçekleştirememiz anlamına gelebilir.

Ne demek bu ? Yani her saniye çalışacak bir recursive setTimeout kullanmanız durumunda, önce setTimeout’un içerisindeki fonksiyon çalıştırılacak daha sonra verilen süre kadar beklenip yeniden aynı fonksiyon çalıştırılacaktır. Bu da (fonksiyonun tamamlanma süresi + verilen bekleme süresi) demek oluyor.

Hemen bunu gerçekleştirecek bir fonksiyon yazdım ve olan oldu beklediğim gibi çalışmadı.


var i = 1;

var setTimeoutFunction = setTimeout(function(){
    console.log(i++);
    setTimeout(setTimeoutFunction,1000);
},1000);

İlk örnek konsole’a 1 yazıp bıraktı, beklediğim gibi fonksiyon kendisini çağırmadı. Bir de aşağıdaki gibi artık kullanılmayan yöntemle denedim.


var i = 1;

var setTimeoutFunction = setTimeout(function(){
    console.log(i++);
    setTimeout(arguments.callee,1000);
},1000);

Bu ise sorunsuz çalıştı. Sebep ise ilk örnekte setTimeoutFunction’ın fonksiyonun kendisini değil de ilgili değişkene integer unique bir değer döndürmesiydi. Bu değer daha sonra clearTimeout fonksiyonunda ilgili setTimeout fonksiyonunu çalışmaz hale getirmek için kullanılıyormuş. Bunun dışında derin bir manası yok bildiğim kadarıyla. Örneğin:


clearTimeout(setTimeoutFunction); //sayacı durdurur

Aynı recursive kullanımı bir de self executive fonksiyon ile yapıp konuyu noktalayalım.

var i = 1;
var stillRunning = true;

(function setTimeoutFunction(){
	console.log(i++);
	if(stillRunning)
	{
		setTimeout(setTimeoutFunction,1000);
	}
})();

Burada diğerlerinden farklı olarak stillRunning isimli global bir değişken tanımladım. Programlamatik olarak bu değişken setlenerek, ilgili recursive fonksiyon durdurulabilir.

Eşit Eşit Eşit de Neyin Nesi ?

Javascript’de === , !== operatörleri katı karşılaştırma operatörleri ( strict comparison operators ) olarak bilinirler.  == ve != ile tip bağımsız karşılaştırmalar yapabilirken, bu operatörler karşılaştırma yaparken tipleri gözardı etmez.

Aşağıdaki örnek üzerinden bunlar arasındaki farkı daha iyi anlayabileceksiniz.


C#’da ya da JAVA’da bu tip operatörler bulunmamakla birlikte, eğer olsaydı herhalde şunun gibi birşey olurdu.

bool TripleEqual(object obj1, object obj2)
{
        return obj1.GetType() == obj2.GetType() && obj1.Equals(obj2);
}

parseInt Kullanımına Dikkat

Projelerimizin birinde JSON olarak aldığımız verilerden bir kısmını işlerken javascript’in parseInt methodundan yararlanıyorduk. "gün/ay/yıl" formatında gelen bir tarih stringini (örn: 08/12/2011) parçalarına ayırıp bir takım işlemlere tabi tutuyorduk.

Ancak burada parseInt("08")' ve parseInt("09")‘un 0 değerini döndürdüğünü farkettik. Kısa bir araştırma sonucu parseInt’in 8′lik tabanda çalıştığını öğrendik. Artık bu fonksiyonu kullanırken parseInt(deger,taban) şeklinde kullanıyor olacağım.


parseInt('01'); //eşittir 1
parseInt('02'); //eşittir 2
parseInt('03'); //eşittir 3
parseInt('04'); //eşittir 4
parseInt('05'); //eşittir 5
parseInt('06'); //eşittir 6
parseInt('07'); //eşittir 7
parseInt('08'); //eşittir 0
parseInt('09'); //eşittir 0

İlgili Html Elementinin Dışına Tıklanma Olayını Yakalama

Genellikle açılır menülerde sıkça rastlanılan bir senaryo diyebiliriz. Bir elemente tıklanır ya da fare ile üzerine gelinir ve daha sonra bunun kendisi dışında sayfada herhangi bir yere tıklanılması durumunda kapatılması istenir. Bu elbette birçok şekilde yapılabilir. Stackoverflow‘da rastladığım aşağıdaki yöntem bence gayet güzel bir çözüm olmuş. Siz de varsa eğer kendi çözümlerinizi paylaşabilirsiniz.


var isMouseInside = false;

$(function()
{
    $('.ilgiliElement').hover(function(){
        isMouseInside = true;
    }, function(){
        isMouseInside = false;
    });

    $("body").mouseup(function(){
        if(!isMouseInside)
          $('.ilgiliElement').hide();
    });
});

setTimeout’u setInterval Gibi Kullanmak ( Kendini Çağıran Fonksiyon Yapısı )

Javascript’de bazen bir işlemi belli aralıklarla tekrar tekrar yapmamız gerekir. Bunun için de genelde setInterval methodu tercih edilir.

Her 2 saniyede bir sayfadaki bir panel içerisinde bilgilerin veritabanı sorgusu yapılarak güncellenmesini istebiliriz. Ancak gözden kaçırabileceğimiz durum, çalışan fonksiyon 2 saniye içerisinde tamamlanamayabilir.  Bu durumunda setInterval işlem bitmeden aynı fonksiyonu ikinci kez çalıştıracaktır. Böyle bir senaryoyu engellemek için javascriptin kendini çağıran fonksiyon yapısını setTimeout ile kullanmak daha mantıklı olabilir.

(function(value){
	alert(value);
	setTimeout(arguments.callee,2000);
})("61")

Kullanım şeklinin rahat anlaşılması için örneği basit tuttum. Burada alert yerine uzun bir işlem sürecine sahip bir yapı düşenebilirsiniz.

İyi çalışmalar,

Önceki Yazılarım