<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【每日一題】為什么使用 setTimeout 實(shí)現(xiàn) setInterval?

          共 2090字,需瀏覽 5分鐘

           ·

          2021-09-02 01:55

          人生苦短,總需要一點(diǎn)儀式感。比如學(xué)前端~

          分析

          setInterval 的作用是每隔一段指定時(shí)間執(zhí)行一個(gè)函數(shù),但是這個(gè)執(zhí)行不是真的到了時(shí)間立即執(zhí)行,它真正的作用是每隔一段時(shí)間將事件加入事件隊(duì)列中,只有當(dāng)目前的執(zhí)行棧為空的時(shí)候,才能去事件隊(duì)列中取出事件執(zhí)行。

          所以可能會(huì)出現(xiàn)這樣的情況:若當(dāng)前執(zhí)行棧執(zhí)行的時(shí)間很長(zhǎng),導(dǎo)致事件隊(duì)列里邊積累多個(gè)定時(shí)器加入的事件,當(dāng)執(zhí)行棧結(jié)束的時(shí)候,這些事件會(huì)依次執(zhí)行,因此可能就不能實(shí)現(xiàn)“到間隔一段時(shí)間執(zhí)行”的效果

          針對(duì) setInterval 的這個(gè)缺點(diǎn),我們可以使用 setTimeout 遞歸調(diào)用來(lái)模擬 setInterval,這樣我們就能確保實(shí)現(xiàn)“一個(gè)事件結(jié)束了、才觸發(fā)下一個(gè)定時(shí)器事件”的效果,以解決了 setInterval 的問(wèn)題。

          模擬實(shí)現(xiàn)

          接下來(lái)我們使用 setTimeout 模擬實(shí)現(xiàn) setInterval,思路是使用遞歸函數(shù),不斷地執(zhí)行 setTimeout 從而達(dá)到 setInterval 的效果。

          簡(jiǎn)單實(shí)現(xiàn)

          代碼實(shí)現(xiàn)

          function mySetInterval(fn, interval{
            // 設(shè)置遞歸函數(shù),模擬定時(shí)器執(zhí)行。
            function callback({
              fn();
              setTimeout(callback, interval);
            }
            // 啟動(dòng)定時(shí)器
            setTimeout(callback, interval);
          }

          執(zhí)行測(cè)試

          var i = 0

          mySetInterval(() => {
            i++;
            console.log(i, '測(cè)試打印')
          }, 1000);
          測(cè)試結(jié)果

          進(jìn)階版:控制是否繼續(xù)執(zhí)行

          function mySetInterval(fn, interval{
            // 控制器,控制定時(shí)器是否繼續(xù)執(zhí)行
            var timer = {
              flagtrue,
            };

            // 設(shè)置遞歸函數(shù),模擬定時(shí)器執(zhí)行。
            function callback({
              if (timer.flag) { // 判斷是否繼續(xù)執(zhí)行
                fn();
                setTimeout(callback, interval);
              }
            }
            // 啟動(dòng)定時(shí)器
            setTimeout(callback, interval);
            // 返回控制器
            return timer;
          }

          // 使用
          let timer = mySetInterval(() => {
            console.log(123)
          }, 1000)
          setTimeout(() => {
            timer.flag = false
          }, 4000)
          測(cè)試結(jié)果

          END
          愿你歷盡千帆,歸來(lái)仍是少年。


          讓我們一起攜手同走前端路!

          關(guān)注公眾號(hào)回復(fù)【加群】即可

          ● 工作中常見(jiàn)頁(yè)面布局的n種實(shí)現(xiàn)方法

          ● 三欄響應(yīng)式布局(左右固寬中間自適應(yīng))的5種方法

          ● 兩欄自適應(yīng)布局的n種實(shí)現(xiàn)方法匯總

          ● 工作中常見(jiàn)的兩欄布局案例及分析

          ● 垂直居中布局的一百種實(shí)現(xiàn)方式

          ● 常用九宮格布局的幾大方法匯總

          ● 為什么操作DOM會(huì)影響WEB應(yīng)用的性能?

          ● 移動(dòng)端滾動(dòng)穿透的6種解決方案

          ● Vue + TypeScript 踩坑總結(jié)

          瀏覽 66
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰黄色在线 | www.99热这里只有精品 www国产夜插内射视频网站 | www色婷婷 | 美女扒开嫩嫩的尿口让人桶 | 久久人爽|