[ Web Proxy ]
URL:
Viewing: https://tr.javascript.info/settimeout-setinterval [Back]  [Original]

Zamanlama: setTimeout ve setInterval
TR

Bu ak-kaynakl projenin tm dnyada kullanlabilir olmasn istiyoruz.

Kendi dilinizde eviriye yardm edebilirsiniz!

    Javascript.info'da ara:
    Eitimde ara:
    Light themeDark theme
    DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

    Zamanlama: setTimeout ve setInterval

    Bir fonksiyon hemen altrlmak istenmeyebilir, belirli bir zaman sonra almas istenebilir. Buna ary zamanlama denir.

    Bunun iin iki metod var:

    • setTimeout fonksiyonu belirli bir zaman sonra altrmaya yarar.
    • setInterval fonksiyonun belirli aralklar ile srekli almasn salar.

    Bu metodlar JavaScriptin tanmlar arasnda yer almaz. Fakat ou ortam bu metodlar sunar. Daha zele inecek olursak tm tarayclar ve NodeJS bu metodlar salar.

    setTimeout

    Yazm:

    let zamanlayiciId = setTimeout(fonk|kod, bekleme[, arg1, arg2...])

    Parametreler:

    fonk|kod
    Fonksiyon veya altrlacak kodun karakter dizisi hali. Genelde bu fonksiyon olur. Uyumluluk dolaysyla karakter dizisi de gnderilebilir fakat nerilmez.
    bekleme
    Milisaniye cinsiden almadan nceki bekleme sresi.(1000 ms = 1 saniye).
    arg1, arg2
    Fonksiyon iin gerekli argmanlar.( IE9 ncesinde almaz.)

    rnein aadaki kod selamVer() fonksiyonunu bir saniye sonra altrr:

    function selamVer() {
      alert('Selam');
    }
    
    setTimeout(selamVer, 1000);

    Argmanl versiyonu:

    function selamVer(ifade, kim) {
      alert( ifade + ', ' + kim );
    }
    
    setTimeout(selamVer, 1000, "Merhaba", "Ahmet"); // Merhaba, Ahmet

    Eer ilk argman karakter dizisi ise, sonrasnda JavaScript bundan fonksiyon retir.

    Aadaki de ayn ekilde alacaktr:

    setTimeout("selamVer('Merhaba')", 1000);

    Karakter dizisi olarak fonksiyon gndermek aslnda pek nerilmez, bunun yerine aadaki gibi fonksiyon kullanlmas daha dorudur:

    setTimeout(() => alert('Merhaba'), 1000);
    Fonksiyon gnder fakat altrma.

    Yeni balayan arkadalar bazen yanllkla fonksiyonun sonuna () ekleyebilir:

    // yanl!
    setTimeout(selamVer(), 1000);

    Bu almaz, nk setTimeout referans bir fonksiyon beklemektedir. Burada selamVer() derseniz fonksiyonu altrrsnz ve bunun sonucu setTimeout fonksiyonu tarafndan kullanlr. Bizim durumumuzda selamVer() undefined dndrr. ( fonksiyon ile alakal bir sorun yok ) bundan dolay hibir ey zamanlanmaz.

    clearTimeout fonksiyonu ile iptal etme

    setTimeout ars timer identifier dner. Bu timerId ile zamanlaycy iptal edebiliriz.

    Yazm aadaki gibidir:

    let timerId = setTimeout(...);
    clearTimeout(timerId);

    Aadaki kodda nce bir zamanlayc test eder sonrasnda ise bunu iptal eder. Sonu olarak hibir ey olmaz:

    let timerId = setTimeout(() => alert("Bir ey olmayacak"), 1000);
    alert(timerId); // timer identifier
    
    clearTimeout(timerId);
    alert(timerId); // same identifier (iptal ettikten sonra null olmaz)

    alert ktsndan da greceiniz gibi timer bir id numaras ile tanmlanr. Dier ortamlarda bu baka bir ey olabilir. rnein Node.Js bir say yerine farkl metodlar olan timer objesi dner.

    Tekrar sylemek gerekirse zerinde anlalm bir artname bulunmamaktadr.

    Tarayclar iin zamanlayclar zamanlayc blmnde belirtilmitir.

    setInterval

    setInterval setTimeout ile ayn yazma sahiptir:

    let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...)

    Tm argmanlar ayn anlama gelir. Fakat setTimeouta nazaran fonksiyonu sadece bir defa deil belirtilen zamanda srekli olarak altrr.

    Bu zamanlaycy iptal etmek iin clearInterval(timerId) kullanlmaldr.

    Aadaki rnekte mesaj her iki saniyede bir gnderilecektir. 5 saniye sonunda ise durdurulur.

    // her iki sn'de tekrar et
    let timerId = setInterval(() => alert('tick'), 2000);
    
    // 5 saniye sonunda durdur.
    setTimeout(() => { clearInterval(timerId); alert('stop'); }, 5000);
    Popup ekrannda Chrome/Opera/Safari zaman durdurur.

    IE ve Firefox tarayclarda ekranda alert/confirm/prompt olduu srece zamanlayc almaya devam eder, fakat Chrome, Opera ve Safari bu zaman durdurur.

    Bundan dolay eer yukardaki kodu altrr ve iptale basmazsanz Firefox/IEde bir sonraki alert durmadan gsterilir. Fakat Chrome/Opera/Safaride kapatldktan sonra 2 sn sonra tekrar alert gelir.

    Tekrarl setTimeout

    Bir kodu dzenli olarak altrmann iki yolu bulunmaktadr.

    lki setInterval dieri ise aadaki gibi kullanlan setTimeout:

    /** instead of:
    let timerId = setInterval(() => alert('tick'), 2000);
    */
    
    let timerId = setTimeout(function tick() {
      alert('tick');
      timerId = setTimeout(tick, 2000); // (*)
    }, 2000);

    setTimeout bir sonraki ary o anki ar bittii ana planlar (*)

    Kendini tekrar eden setInterval setTimeoutdan daha esnektir. Bu ekliyle kullanldnda bir sonraki planlanan ar ana arnn durumuna gre telebilir veya daha geriye alnabilir.

    rnein, her 5 snde bir sunucudan veri isteyen bir servis yazmamz gerekmektedir. Fakat sunucuya fazladan yk binerse bunun 10,20,40 sn olarak deitirilmesi gerekmektedir.

    Bahsedilen kod aadaki gibidir:

    let delay = 5000;
    
    let timerId = setTimeout(function request() {
      ...talep gnder...
    
      if (sunucu yklenmesinden dolay eer talep iptal olursa) {
        // bir sonraki talep iin gerekli sreyi uzat.
        delay *= 2;
      }
    
      timerId = setTimeout(request, delay);
    
    }, delay);

    Eer CPU-a grevleriniz varsa bu grevlerin sresini lp buna gre bir alma plan oluturmak mmkndr.

    Kendini tekrar eden setInterval iki ar arasndaki sreyi garanti eder fakat setTimeout bunu garanti etmez.

    Aadaki iki kod parac karlatrlacak olursa:

    let i = 1;
    setInterval(function() {
      func(i);
    }, 100);

    kincisi tekrarl setTimeout kullanmaktadr.

    let i = 1;
    setTimeout(function run() {
      func(i);
      setTimeout(run, 100);
    }, 100);

    setInterval func(i) fonksiyonunu her 100msde bir altrr.

    []

    Dikkatinizi ekti mi?

    func arlar arasndaki geen sre koddan daha ksa.

    Doal olan bu aslnda nk func altnda bu arln bir ksmn harcar.

    Hatta bu func almasnn bizim beklediimiz 100msden fazla olmas da mmkndr.

    Bu durumda JS Motoru func fonksiyonunun bitmesini bekler, sonra planlaycy kontrol eder eer zaman gemise hi beklemeden tekrar altrr.

    Bu durumda ile karlaldnda fonksiyon hi beklemeden srekli alr.

    Aada ise kendini aran setTimeout gsterilmitir:

    []

    Kendini aran setTimeout arada geen srenin ayn olmasn garanti eder.(burada 100ms).

    Bunun nedeni yeni arnn nceki arnn bitiminde hesaplanmasndan dolaydr.

    Garbage collection

    Bir fonksiyon setInterval/setTimeouta gnderildiinde ieride bir referansn oluturup zamanlaycya kaydeder. Bundan dolay bu fonksiyon p toplama ilemine girmez. Darda hibir referans olmasa bile bu fonksiyon yok olmaz.

    // zamanlayc arana kadar fonksiyon hafzada kalr.
    setTimeout(function() {...}, 100);

    setInterval metodu iin fonksiyon cancelInterval arlmad srece hafzada kalr.

    Bunun yan etkisi ise, dardaki fonksiyondan veri almak isteyen bir fonksiyon srekli arlr ve ayakta kalrsa dardaki deikenlerin de sreklilii devam eder. Asl bu fonksiyonun kendisinden bile fazla hafza kaplayabilir. yleyse zamanlayc ile iiniz bittiinde en iyisi iptal etmektir. Bu fonksiyonunuz kk olsa bile yaplmas gereken bir ilemdir.

    setTimeout(,0)

    setTimeOutun farkl bir kullanm ekli daha bulunmakta: setTimeout(func, 0)

    Bu funcn mmkn olduu anda zamanlanmasn salar. Fakat zamanlayc bunu sadece o anki kod ilemi bittiinde gerekletirir.

    Bundan dolay zamanlayc o anki iin hemen arkasndan almaya balar. Dier bir deyile asenkron.

    rnein aadaki kod nce Merhaba ve hemen arkasndan Dnya yazdrr.

    setTimeout(() => alert("Dnya"), 0);
    
    alert("Merhaba");

    lk satrda ary 0ms sonra sraya koy demektir. Fakat zamanlayc bunu nce sray kontrol et'ten sonra bakar yani o anki kodu altrdktan sonra. Bundan dolay "Merhaba" nce yazlr "Dnya" sonra.

    CPU-a grevlerin paralanmas

    setTimeout ile CPU-a grevlerin kullanlabilmesi yle bir yntem kullanlabilir.

    rnein, yazlarn renklerini deitiren ( u anki sayfa gibi ) bir uygulama tam olarak CPU-a bir uygulamadr. Analiz eder, birok renkli eleman yaratr, bunlar dkmana ekler dosya bydke bu da gittike daha fazla ilemci gerektirir. Hatta taraycnn "hang " durumuna yani tepki vermemesine kadar gidebilir, bu da kabul edilemez.

    Bundan dolay uzun metinleri ayrabiliriz. nce 100 satr, sonra dier bir 100 satr vs.

    Daha basit bir rnekten anlatmaya alrsak. Bir fonksiyonunuz olsun ve 1den 100000000000a kadar saysn

    Eer kodu altrrsanz ilemci tepki vermemeye balar. Sunucu tabanl JS kodlarnda bu kolay bir ekilde fark edilebilir fakat eer bu kodu tarayc zerinde altryorsanz dier butonlara tkladnzda JavaScriptin durduunu ve bunun bitene kadar da baka bir eyin almadn grrsnz.

    let i = 0;
    
    let start = Date.now();
    
    function count() {
    
      // youn bir i
      for(let j = 0; j < 1e9; j++) {
        i++;
      }
    
      alert((Date.now() - start) + 'ms de tamamland');
    }
    
    count();

    Hatta taryc bu kodun almas uzun zaman alyor uyars verebilir.

    Kodu setTimeout ile blecek olursak:

    let i = 0;
    
    let start = Date.now();
    
    function count() {
    
      // zorlu grevin bir blmn yap (*)
      do {
        i++;
      } while (i % 1e6 != 0);
    
      if (i == 1e9) {
        alert((Date.now() - start) + 'ms de tamamland');
      } else {
        setTimeout(count, 0); // yeni ary zamanla (**)
      }
    
    }
    
    count();

    imdi tarayc ekran sayma ilemi gerekleirken tamamen alr durumdadr.

    in bir blm u ekilde yaplr (*)

    1. lk alma: i=1...1000000.
    2. ikinci alma: i=1000001..2000000
    3. bu ekilde while i nin 100000e blnp blnmediine kadar.

    Eer ilem hala bitmemise (**) zamanlaycs tekrar alr.

    Saya alrken duraklama yaplmas JavaScript motoruna nefes almas ve baka i yapabilmesi iin zaman salar.

    Dikkat edilmesi gereken nokta: setInterval kullanlarak ve kullanlmadan yaplan iki testin alma sreleri ok farkl deildir.

    Bu sreleri daha da yaknlatrabilmek iin neler yaplabilir bakalm.

    Zamanlamay count() fonksiyonunun bana alalm:

    let i = 0;
    
    let start = Date.now();
    
    function count() {
    
      // zamanlama baa tand
      if (i < 1e9 - 1e6) {
        setTimeout(count, 0); // yeni ary zamanla
      }
    
      do {
        i++;
      } while (i % 1e6 != 0);
    
      if (i == 1e9) {
        alert((Date.now() - start) + 'ms de tamamland');
      }
    
    }
    
    count();

    imdi ise count() ile balyoruz ve count fonksiyonunun birden fazla arlacanz biliyoruz.

    altrrsanz belirgin biimde daha ksa sreceini greceksiniz.

    Browserdaki i ie zamanlayclarn arasnda bulunan minimum gecikmeler

    Taraycda, i ie zamanlayclarn kullanmna ait bir limit bulunmaktadr. HTML5 standard dediine gre: 5 i ie zamanlaycdan sonra, dng en az 4 ms durmak zorundadr.

    Bunu aadaki bulunan rnekte gsterelim. setTimeout ars kendisini 0ms sonra tekrarn aryor. Her bir ar bir ncekinin zamann times dizisinden hatrlyor. Gecikme nasl olacak bakalm:

    let start = Date.now();
    let times = [];
    
    setTimeout(function run() {
      times.push(Date.now() - start); // bir nceki ardaki gecikmeyi hatrla.
    
      if (start + 100 < Date.now()) alert(times); // gecikme 100ms den bykse gster
      else setTimeout(run, 0); // deilse tekrar zamanla
    }, 0);
    
    // ktnn rnei:
    // 1,1,1,1,9,15,20,24,30,35,40,45,50,55,59,64,70,75,80,85,90,95,100

    lk zamanlayclar annda alacaktr ( dkmantasyonda yazd gibi ) bundan dosnra gecikmeler oyuna dahil olur. 9, 15, 20, 24...

    Bu limitasyonlarn nedeni de yine eski zamanlara dayanmaktadr. ou kod bu prensibe gre altndan dolay bu kurallar devam etmektedir.

    Sunucu tabanl JavaScript iin ise bu kstlama geerli deildir. Ayrca anlk olarak asenkronron ilerin zamanlamas amacyla baka yollar da bulunmaktadr. rnein process.nextTick ve setImmediate gibi. Yani buradaki kstlamann tarayc bazl olduu sonucunu karabilirsiniz.

    Taraycnn ilemesine izin vermek.

    Tarayc tarafl kodlarn dier bir yarar ise kullancya progresss bar(ilerleme ubuu) tarznda grselleri sunabilmesidir. Tarayc genelde tekrar boyama kod tekrarlandktan sonra ( repainting) ilemi yaptndan.

    Bundan dolay diyelim ki ok byk iler yapan bir fonksiyon olsa bile, dkmanda bulunan deiiklik bu ilem tamamlandktan sonra gerekleir.

    rneiN:

    <div id="progress"></div>
    
    <script>
      let i = 0;
    
      function count() {
        for(let j = 0; j < 1e6; j++) {
          i++;
          // anlk i deerini dive yazdr. <div>
          // ( innerHTML ile ilgili daha sonraki blmlerde konuulacaktr.)
          progress.innerHTML = i;
        }
      }
    
      count();
    </script>

    Bunu altdnzda inin deiiklii tm sayma ilemi bittikten sonra grnr hale gelir.

    eer bunu setTimeout ile paralara blecek olursak bu defa daha gzel bir ekilde grnecektir.

    <div id="progress"></div>
    
    <script>
      let i = 0;
    
      function count() {
    
        // youn iin bir blm (*)
        do {
          i++;
          progress.innerHTML = i;
        } while (i % 1e3 != 0);
    
        if (i < 1e9) {
          setTimeout(count, 0);
        }
    
      }
    
      count();
    </script>

    Artk <div> i nin ykselen deerini gsterecektir.

    zet

    • setInterval(func, delay, ...args) ve setTimeout(func, delay, ...args) metodlar funcn dzenli olarak delay ms aralklar ile almasn salar.
    • almay durdurmak iin clearInterval/clearTimout fonksiyonlar setInterval/setTimeout metodundan dnen deerler ile arlmaldr.
    • ie setTimeout ars kullanmak setIntervale gre daha esnektir. Ayrca bu ekilde aralarda en ksa sre beklemesini salar.
    • 0 gecikmeli zamanlayc ise setTimeout(...,0) zamanlaycy olabildiince abuk fakat o anki koddan sonra arlacak ekilde zamanlar.

    setTimeout(...,0)'n baz kullanm durumlar:

    • CPU-a grevleri paralara ayrmak iin, bylece kod srekli tepki verebilir.
    • Bylece grev devam ederken taraycnn baka ilere ( ilerleme ubuu ) zaman ayrr.

    Tm zamanlama metodlar tam olarak gecikmeyi garantilemez. Zamanlaycda bu varsaymn zerine bir ey ina etmeyin.

    rnein, tarayc zaman birok nedenden tr yavalayabilir:

    • lemcinin yk artarsa.
    • Taraycnn tab arka plana alndysa.
    • Laptop batarya ile alyorsa.

    Bunlarn hepsi tarayc zamanna etki eder. Aralardaki gecikme 300ms ile 1000ms arasnda deiebilir. Tabi tarayc ve zellikleri de bu konuda etkin rol oynar.

    Grevler

    nem: 5

    printNumbers(from, to) adnda bir fonksiyon yazn ve bu fonksiyon baslangictan bitis'e kadar her saniye bir say yazdrsn.

    Bunun iki iki versiyonunu da yaznz.

    1. setInterval kullanarak.
    2. Kendini tekrar eden setTimeout kullanarak.
    zm

    setInterval:

    function printNumbers(from, to) {
      let current = from;
    
      let timerId = setInterval(function() {
        alert(current);
        if (current == to) {
          clearInterval(timerId);
        }
        current++;
      }, 1000);
    }
    
    // usage:
    printNumbers(5, 10);

    setTimeout kullanilarak:

    function printNumbers(from, to) {
      let current = from;
    
      setTimeout(function go() {
        alert(current);
        if (current < to) {
          setTimeout(go, 1000);
        }
        current++;
      }, 1000);
    }
    
    // kullanimi:
    printNumbers(5, 10);

    ki zmde de ilk kt iin bir gecikme sz konusudur. Bazen bir satr ekleyerek ilk ktnn hemen verilmesini salayabilirsiniz.

    If we also want the function to run immediately, then we can add an additional call on a separate line, like this:

    function printNumbers(from, to) {
      let current = from;
    
      function go() {
        alert(current);
        if (current == to) {
          clearInterval(timerId);
        }
        current++;
      }
    
      go();
      let timerId = setInterval(go, 1000);
    }
    
    printNumbers(5, 10);
    nem: 4

    Aada setTimeout ile bir grevi paralara ayran bir fonksiyon bulunmaktadr.

    Bu fonksiyonu setInterval ile tekrar yaznz:

    let i = 0;
    
    let start = Date.now();
    
    function count() {
    
      if (i == 1000000000) {
        alert("Done in " + (Date.now() - start) + 'ms');
      } else {
        setTimeout(count, 0);
      }
    
      // zorlu bir grev
      for(let j = 0; j < 1000000; j++) {
        i++;
      }
    
    }
    
    count();
    zm
    let i = 0;
    
    let start = Date.now();
    
    let timer = setInterval(count, 0);
    
    function count() {
    
      for(let j = 0; j < 1000000; j++) {
        i++;
      }
    
      if (i == 1000000000) {
        alert((Date.now() - start) + 'ms ierisinde tamamland');
        cancelInterval(timer);
      }
    
    }
    nem: 5

    Aadaki kodda zamanlanm bir setTimeout ars bulunmaktadr. Sonrasnda 100ms srecek bir hesap gereklidir.

    Zamanlanm fonksiyon ne zaman alacak ?

    1. Dng bittikten sonra
    2. Dngden nce
    3. Dngnn banda

    alert ne gsterecek?

    let i = 0;
    
    setTimeout(() => alert(i), 100); // ?
    
    // bu fonksiyonu alma zaman >100 ms varsayn.
    for(let j = 0; j < 100000000; j++) {
      i++;
    }
    zm

    setTimeoutlarn hepsi o anda alan kod bittikten sonra balar.

    i en son 100000000 olacaktr.

    let i = 0;
    
    setTimeout(() => alert(i), 100); // 100000000
    
    // bu fonksiyonu alma zaman >100 ms varsayn.
    for(let j = 0; j < 100000000; j++) {
      i++;
    }
    Eitim haritas

    Yorumlar

    yorum yapmadan nce ltfen okuyun...
    • Eer gelitirme ile alakal bir neriniz var ise yorum yerine github konusu gnderiniz.
    • Eer makalede bir yeri anlamadysanz ltfen belirtiniz.
    • Koda birka satr eklemek iin <code> kullannz, birka satr eklemek iin ise <pre> kullann. Eer 10 satrdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)

    Web Proxy Viewer  |  New URL  |  Original Page