整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          javascript定時器setInterval的基本用法

          家啊可能經常在各大網站上看到這樣一個功能就是跳動的時鐘,一秒一秒的不停

          的變化。今天這個小分享呢就給大家分享一下怎么用javascript來實現這種隨處

          可見的小功能

          開發功能“軌跡播放”時,遇到了一個情況。
          原先同事已經開發了一版,這次有個新功能:點擊線上任意一點后可以從點擊處重新播放。
          看了一下原來的版本,發現同時使用了setTimeout和setInterval,兩者配合實現點線播放。
          簡單結構如下

           function test() {
           setInterval(function () {
           console.log("interval");
           //省略插值方法得到arr
           (...)
           play(arr);
           }, 2000);
           }
           function play(arr) {
           setTimeout(function () {
           play(arr);
           console.log("setTimeout");
           }, 40);
           }

          我覺得這個結構欠妥,兩個定時器配合必定會出現失誤!因此重構了一版,將兩個定時器改為一個,用setInterval解決。
          但是此時我并不知道欠妥欠在什么地方,缺乏理論支持,現在閑下來仔細研究了一下

          0|1找問題

          在仔細研究了舊版本后,我先把舊版本結構扒了出來,排除其他因素,自己模擬了一個簡單版(就是上面的代碼)
          setTimeout:在執行時,是在載入后延遲指定時間后,去執行一次表達式,僅執行一次
          setInterval:在執行時,它從載入后,每隔指定的時間就執行一次表達式

          • 實驗一:在使用setInterval和setTimeout方法上,并沒有什么問題,決定跑一下,結果如下

          從結果得出兩點結論

          1. setTimeout與setInterval并不是50倍速度配合運行著
          2. 兩次interval間,timeout運行的次數越來越多,表明setInterval運行間隔越來越長,延遲越來越大
          • 實驗二:加一點人工干預再執行
           function test() {
           setInterval(function () {
           console.log("interval");
           play();
           }, 2000);
           }
           function play() {
           //延遲執行
           for (var i = 0; i < 100000000; i++) {
           
           }
           setTimeout(function () {
           play();
           console.log("setTimeout");
           }, 40);
           }

          從結果得出兩點結論

          1. setInterval可能會隨函數處理時間,減少間隔
          2. 推測,因為Javascript是單線程的,setInterval和setTimeout是放隊列里執行的,很容易受到回調事件影響
          • 實驗三:拖動縮放瀏覽器

          從結果得出結論

          1. 當瀏覽器標簽切換到其他頁面,或者瀏覽器最小化,會影響計時器,兩者會出現間隔減小

          0|1涉及知識點

          綜上實驗結果,網上搜集了一些資料能說明問題:

          1. JavaScript是單線程,但是瀏覽器是多線程,Javascript是瀏覽器多線程中的一個線程。(圖參考自:https://www.cnblogs.com/tesky0125/p/4619549.html)

          1. Javascript會把執行的回調函數、瀏覽器的觸發事件、UI渲染事件,先放到隊列中,隊列根據先進先出的規則,依次執行他們,當執行到隊列中的setInterval時很難保證其與setTimeout同步關系還保持。
          2. setInterval無視代碼錯誤:代碼報錯,但是setInterval依舊會按時執行,不會中斷。
          3. setInterval無視網絡延遲:如果調用ajax或其他服務,他不會管是否返回回調,會繼續按時執行。
          4. setInterval不保證執行:因為setInterval會定時執行,如果函數邏輯很長,間隔時間內執行不完,后續方法會被拋棄。
          5. 會受瀏覽器狀態影響,tab切換、最小化等

          0|1解決方案

          在做軌跡播放時,setInterval的延遲還在可接受范圍之內,但是網上給出的最佳解決方案是用setTimeout做。
          setTimeout只會執行一次,在執行完成后,重新啟動新的Timeout,時間runtime計算設置為差時,減少出現間隔越來越大的情況

          近需要網頁添加多個倒計時. 查閱網絡,基本上都是千遍一律的不好用. 自己按需寫了個.希望對大家有用. 有用請贊一個哦!

          //js

          //js2

          var plugJs={

          stamp:0,

          tid:1,

          stampnow:Date.parse(new Date())/1000,//統一開始時間戳

          intervalTime:function(){

          if(plugJs.stamp > 0){

          var day = Math.floor(plugJs.stamp / (60 * 60 * 24));

          var hour = Math.floor(plugJs.stamp / (60 * 60)) - (day * 24);

          var minute = Math.floor(plugJs.stamp / 60) - (day * 24 * 60) - (hour * 60);

          var second = Math.floor(plugJs.stamp) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60);

          if (day <= 9) day = '0' + day;

          if (hour <= 9) hour = '0' + hour;

          if (minute <= 9) minute = '0' + minute;

          if (second <= 9) second = '0' + second;

          jQuery('.t_h_'+plugJs.tid).html(hour);

          jQuery('.t_m_'+plugJs.tid).html(minute);

          jQuery('.t_s_'+plugJs.tid).html(second);

          plugJs.stamp--;

          setTimeout('if(typeof(plugJs.intervalTime) == "function"){plugJs.intervalTime();}',1000);

          }

          },

          timer:function (stampend,tid){

          plugJs.stamp = parseInt(stampend)-parseInt(plugJs.stampnow);//剩余時間戳

          setTimeout('if(typeof(plugJs.intervalTime) == "function"){plugJs.intervalTime();}',1000);

          }

          };

          jQuery(document).ready(function(){

          var stampend = parseInt(jQuery('.countdown_1').attr('data-time'));//靈活讀取表里的結束時間戳

          plugJs.timer(stampend,'1');

          });

          //html 原文http://blog.csdn.net/websites/article/details/50037611

          <div class="time countdown_1" data-time="1449429731">

          <span class="t_h_1">00</span>

          <i class="lay_line">:</i>

          <span class="t_m_1">00</span>

          <i class="lay_line">:</i>

          <span class="t_s_1">00</span>

          </div>

          <div class="time countdown_2" data-time="1449456731">

          <span class="t_h_2">00</span>

          <i class="lay_line">:</i>

          <span class="t_m_2">00</span>

          <i class="lay_line">:</i>

          <span class="t_s_2">00</span>

          </div>

          注釋:setTimeout() 只執行 code 一次。如果要多次調用,請使用 setInterval() 或者讓 code 自身再次調用 setTimeout()。


          主站蜘蛛池模板: 免费观看日本污污ww网站一区| 精品女同一区二区三区在线| 在线免费观看一区二区三区| 亚洲一区动漫卡通在线播放| 日本免费一区二区三区| 一区二区中文字幕| 国产综合精品一区二区| 久久精品国产一区二区| 亚洲AV本道一区二区三区四区| 成人区人妻精品一区二区不卡视频| 久久se精品一区精品二区| 久久国产一区二区三区| 国产一区二区三区乱码在线观看| 欧美日韩精品一区二区在线观看| 国模精品一区二区三区视频 | 精品一区二区三区东京热| 亚洲熟妇AV一区二区三区宅男| 一区二区三区亚洲视频| 亚洲一区二区三区高清视频| 国产萌白酱在线一区二区| 亚洲国产精品一区二区三区久久| 蜜臀Av午夜一区二区三区| 欧美日本精品一区二区三区| 亚洲人成人一区二区三区| 无码精品一区二区三区| 亚洲AV无码一区二区三区系列| 女人18毛片a级毛片一区二区| 国产精品女同一区二区 | 午夜爽爽性刺激一区二区视频| 国产av成人一区二区三区| 国产精品久久亚洲一区二区| 亚洲一区二区三区无码国产| 国产一区二区精品久久凹凸| 久久se精品一区二区国产| 亚洲AⅤ无码一区二区三区在线| 中文字幕一区二区三区人妻少妇| 国产视频一区在线观看| 国产福利无码一区在线| 国产麻豆剧果冻传媒一区| 91在线视频一区| 国产SUV精品一区二区四|