专业网站建设_企业品牌营销 · 北京汇仁智杰科技有限公司

Web前端知識

首頁 > 免費 > Web前端知識 >

JavaScript定時器與執行機制解析

來源:北京匯仁智杰科技有限公司   時間:2016-05-25   點擊:

  從JS執行機制說起
  瀏覽器(或者說JS引擎)執行JS的機制是基于事件循環。
  由于JS是單線程,所以同一時間只能執行一個任務,其他任務就得排隊,后續任務必須等到前一個任務結束才能開始執行。
  為了避免因為某些長時間任務造成的無意義等待,JS引入了異步的概念,用另一個線程來管理異步任務。
  同步任務直接在主線程隊列中順序執行,而異步任務會進入另一個任務隊列,不會阻塞主線程。等到主線程隊列空了(執行完了)的時候,就會去異步隊列查詢是否有可執行的異步任務了(異步任務通常進入異步隊列之后還要等一些條件才能執行,如ajax請求、文件讀寫),如果某個異步任務可以執行了便加入主線程隊列,以此循環。
  JS定時器
  JS的定時器目前有三個:setTimeout、setInterval和setImmediate。
  定時器也是一種異步任務,通常瀏覽器都有一個獨立的定時器模塊,定時器的延遲時間就由定時器模塊來管理,當某個定時器到了可執行狀態,就會被加入主線程隊列。
   JS定時器非常實用,做動畫的肯定都用到過,也是最常用的異步模型之一。
  有時候一些奇奇怪怪的問題,加一個setTimeout(fn, 0)(以下簡寫setTimeout(0))就解決了。不過,如果對定時器本身不熟悉,也會產生一些奇奇怪怪的問題。
  setTimeout
  setTimeout(fn, x)表示延遲x毫秒之后執行fn。
  使用的時候千萬不要太相信預期,延遲的時間嚴格來說總是大于x毫秒的,至于大多少就要看當時JS的執行情況了。
  另外,多個定時器如不及時清除(clearTimeout),會存在干擾,使延遲時間更加捉摸不透。所以,不管定時器有沒有執行完,及時清除已經不需要的定時器是個好習慣。
  HTML5規范規定最小延遲時間不能小于4ms,即x如果小于4,會被當做4來處理。 不過不同瀏覽器的實現不一樣,比如,Chrome可以設置1ms,IE11/Edge是4ms。
  setTimeout注冊的函數fn會交給瀏覽器的定時器模塊來管理,延遲時間到了就將fn加入主進程執行隊列,如果隊列前面還有沒有執行完的代碼,則又需要花一點時間等待才能執行到fn,所以實際的延遲時間會比設置的長。如在fn之前正好有一個超級大循環,那延遲時間就不是一丁點了。
  (function testSetTimeout() {
  const label = 'setTimeout';
  console.time(label);
  setTimeout(() => {
   console.timeEnd(label);
  }, 10);
  for(let i = 0; i < 100000000; i++) {}
  })();
  setInterval結果是:setTimeout: 335.187ms,遠遠不止10ms。
  setInterval的實現機制跟setTimeout類似,只不過setInterval是重復執行的。
  對于setInterval(fn, 100)容易產生一個誤區:并不是上一次fn執行完了之后再過100ms才開始執行下一次fn。 事實上,setInterval并不管上一次fn的執行結果,而是每隔100ms就將fn放入主線程隊列,而兩次fn之間具體間隔多久就不一定了,跟setTimeout實際延遲時間類似,和JS執行情況有關。
  (function testSetInterval() {
  let i = 0;
  const start = Date.now();
  const timer = setInterval(() => {
  i += 1;
   i === 5  clearInterval(timer);
  console.log(`第${i}次開始`, Date.now() - start);
  for(let i = 0; i < 100000000; i++) {}
  console.log(`第${i}次結束`, Date.now() - start);
  }, 100);
  })();
  輸出
  第1次開始 100
  第1次結束 1089
  第2次開始 1091
  第2次結束 1396
  第3次開始 1396
  第3次結束 1701
  第4次開始 1701
  第4次結束 2004
  第5次開始 2004
  第5次結束 2307
  另外可以看出,當setInterval的回調函數執行時間超過了延遲時間,已經完全看不出有時間間隔了。可見,雖然每次fn執行時間都很長,但下一次并不是等上一次執行完了再過100ms才開始執行的,實際上早就已經等在隊列里了。
  如果setTimeout和setInterval都在延遲100ms之后執行,那么誰先注冊誰就先執行回調函數。
  setImmediate
  這算一個比較新的定時器,目前IE11/Edge支持、Nodejs支持,Chrome不支持,其他瀏覽器未測試。
  從API名字來看很容易聯想到setTimeout(0),不過setImmediate應該算是setTimeout(0)的替代版。
  在IE11/Edge中,setImmediate延遲可以在1ms以內,而setTimeout有最低4ms的延遲,所以setImmediate比setTimeout(0)更早執行回調函數。不過在Nodejs中,兩者誰先執行都有可能,原因是Nodejs的事件循環和瀏覽器的略有差異。
  (function testSetImmediate() {
  const label = 'setImmediate';
  console.time(label);
  setImmediate(() => {
  console.timeEnd(label);
  });
  })();
  Edge輸出:setImmediate: 0.555 毫秒
  很明顯,setImmediate設計來是為保證讓代碼在下一次事件循環執行,以前setTimeout(0)這種不可靠的方式可以丟掉了。
  其他常用異步模型
  requestAnimationFrame
  requestAnimationFrame并不是定時器,但和setTimeout很相似,在沒有requestAnimationFrame的瀏覽器一般都是用setTimeout模擬。
  requestAnimationFrame跟屏幕刷新同步,大多數屏幕的刷新頻率都是60Hz,對應的requestAnimationFrame大概每隔16.7ms觸發一次,如果屏幕刷新頻率更高,requestAnimationFrame也會更快觸發。基于這點,在支持requestAnimationFrame的瀏覽器還使用setTimeout做動畫顯然是不明智的。
  在不支持requestAnimationFrame的瀏覽器,如果使用setTimeout/setInterval來做動畫,最佳延遲時間也是16.7ms。 如果太小,很可能連續兩次或者多次修改dom才一次屏幕刷新,這樣就會丟幀,動畫就會卡;如果太大,顯而易見也會有卡頓的感覺。
  有趣的是,第一次觸發requestAnimationFrame的時機在不同瀏覽器也存在差異,Edge中,大概16.7ms之后觸發,而Chrome則立即觸發,跟setImmediate差不多。按理說Edge的實現似乎更符合常理。
  (function testRequestAnimationFrame() {
  const label = 'requestAnimationFrame';
  console.time(label);
  requestAnimationFrame(() => {
   console.timeEnd(label);
  });
  })();
  Edge輸出:requestAnimationFrame: 16.66 毫秒
  Chrome輸出:requestAnimationFrame: 0.698ms
  但相鄰兩次requestAnimationFrame的時間間隔大概都是16.7ms,這一點是一致的。當然也不是絕對的,如果頁面本身性能就比較低,相隔的時間可能會變大,這就意味著頁面達不到60fps。
  Promise
  Promise是很常用的一種異步模型,如果我們想讓代碼在下一個事件循環執行,可以選擇使用setTimeout(0)、setImmediate、requestAnimationFrame(Chrome)和Promise。
  而且Promise的延遲比setImmediate更低,意味著Promise比setImmediate先執行。
  function testSetImmediate() {
  const label = 'setImmediate';
  console.time(label);
  setImmediate(() => {
  console.timeEnd(label);
  });
  }
  function testPromise() {
  const label = 'Promise';
  console.time(label);
  new Promise((resolve, reject) => {
  resolve();
  }).then(() => {
  console.timeEnd(label);
  });
  }
  testSetImmediate();
  testPromise();
  Edge輸出:Promise: 0.33 毫秒 setImmediate: 1.66 毫秒
  盡管setImmediate的回調函數比Promise先注冊,但還是Promise先執行。
  可以肯定的是,在各JS環境中,Promise都是最先執行的,setTimeout(0)、setImmediate和requestAnimationFrame順序不確定。
  process.nextTick
  process.nextTick是Nodejs的API,比Promise更早執行。
  事實上,process.nextTick是不會進入異步隊列的,而是直接在主線程隊列尾強插一個任務,雖然不會阻塞主線程,但是會阻塞異步任務的執行,如果有嵌套的process.nextTick,那異步任務就永遠沒機會被執行到了。
  使用的時候要格外小心,除非你的代碼明確要在本次事件循環結束之前執行,否則使用setImmediate或者Promise更保險。

網絡營銷推廣 . 北京匯仁智杰科技有限公司!

地址:北京市昌平區回龍觀龍冠大廈5層
咨詢:13370157521
業務QQ:373002979
E - mail:sales @ huirenzhijie.com
企業網站備案:京ICP備15021091號-1

匯仁智杰與眾不同

  • 有網絡推廣經驗
  • 有網站建站隊伍
  • 有大型網站建設經驗
  • 致力于營銷型網站建設
  • 始終堅持技術和服務同樣重要
查看PC版網站
備案號:京ICP備15021091號-1 版權所有:匯仁智杰

主站蜘蛛池模板: 纸箱抗压测定仪|电脑测控耐破度仪|电脑抗张试验仪|杭州华翰仪器百科 | 少妇厨房与子伦_污污内射久久一区二区欧美日韩_四房婷婷 | 山东装卸登车桥_液压装卸升降平台_固定|移动登车桥_山东牛斗重工厂家 | 新余市国信融资担保有限公司| 远东齿轮泵|高粘度齿轮泵|三螺杆油泵|沥青保温泵|高粘度稠油泵-远东泵业官网 | 衡水一体化污水处理设备|循环水旁滤器|加药装置|钢厂浊环净化装置|河北欧意科技集团有限公司 | 阻垢剂|缓蚀剂|杀菌剂|分散剂|水处理剂|印染助剂|水处理药剂|造纸助剂|膜阻垢剂|缓蚀剂|HEDP|ATMP|螯合剂-山东凯瑞化学有限公司 水处理药剂生产厂家 | 深圳注册公司-工商注册代理-深圳注册公司流程及费用-记帐报税-公司注销-[深圳市悟空企业管理(深圳)有限公司] | 趣看科技-视频新媒体技术一体化专业服务商 | 西安墓园-山水殡葬服务-提供免费墓地咨询服务 | 商标注册查询_商标注册代理公司_专利申请_版权登记-源智知识产权 | 深圳沃亚游学官网丨国外游学丨国际夏冬令营丨美国游学线路丨出国短期游学丨亲子海外游丨游学咨询: 0755-83843308 | 景德镇古窑民俗博览区-国家AAAAA级旅游景区_全国旅游标准化示范景区_国家文化产业示范基地_国家级非物质文化遗产生产性保护示范基地--官方网站 | 郑州同林-金属切削液,全合成,半合成,防锈水溶性,微乳,油基长寿乳化切削液生产厂家 | 太原重卡叔叔运输有限公司-山西太原大件运输、太原物流公司、太原货运物流、太原大件运输、太原货运信息、长治物流公司、长治大件运输、晋城物流公司、晋城大件运输、忻州大件运输、朔州大件运输、阳泉大件运输、大同大件运输、吕梁大件运输、临汾大件运输、运城大件运城 | 九江市京邦玻纤有限公司| 石家庄华龙鼎电动门,石家庄电动门电话,石家庄电动门配件,石家庄电动门维修电话,石家庄电动门安装电话,石家庄华龙电动门 | 河北撒旺肥业有限公司| 西安真石漆_无机涂料厂家_无机涂料多少钱一个平方—陕西秦森环保科技有限公司 | 门禁控制器-自动道闸-停车场系统-车位引导系统-车牌识别系统-楼宇对讲-可视门铃-门禁一卡通-河北京鹏电子科技有限公司 | 转轴测试机-按键寿命测试机-连接器插拔力试验机-深圳市丹荣检测 转盘萃取塔,DMF回收塔生产厂家-无锡弘鼎华化工设备有限公司 | 长沙广告设计公司|长沙广告制作|湖南户外广告制作|商业美陈就找湖南盛翔文化传媒有限公司老品牌高品质 | 山东向阳电子科技有限公司-多用户集中式电能表生产厂家,NB物联网水表,刷卡水电表生产厂家,泰安智能水电表价格 | 青州东威机械有限公司,洗沙机,脱水筛、细沙回收机,淘金设备,洗石机,砂石分离机,筛沙机,采沙船,清淤船,破碎制砂机,海沙淡化设备 | 苏州不锈钢_江苏不锈钢_江苏不锈钢板_苏州模具钢_苏州合金钢_苏州特种合金_苏州不锈钢板_304不锈钢棒_苏州塞硒五金制品有限公司 苏州ERP定制|苏州CRM|苏州OA|苏州BPM|进销存管理系统-苏州中尚信息科技有限公司 | 郑州月嫂|月嫂培训|月嫂服务|郑州布卢家政服务有限公司 | 呼吸家官网|肺功能检测仪生产厂家|国产肺功能仪知名品牌|肺功能检测仪|肺功能测试仪|婴幼儿肺功能仪|弥散残气肺功能仪|肺功能测试系统|广州红象医疗科技有限公司|便携式肺功能仪|大肺功能仪|呼吸康复一体机|儿童肺功能仪|肺活量计|医用简易肺功能仪|呼吸康复系统|肺功能仪|弥散肺功能仪(大肺)|便携式肺功能检测仪|肺康复|呼吸肌力测定肺功能仪|肺功能测定仪|呼吸神经肌肉刺激仪|便携式肺功能 | 制沙机,反击式破碎机,重锤破碎机,泥石分离机,圆锥破碎机厂家-昆明德鑫机械 | 无土栽培|无土栽培技术|水肥一体化|无土栽培蔬菜| 河北湛存边坡防护工程有限公司-边坡防护网_边坡绿化修复_喷浆挂网 | 线路板生产厂家|电路板快板打样|PCB工厂价格|江西锦宏电子有限公司|PCB版加工定制 | 军用笔记本电脑_三防加固笔记本电脑_平板型全坚固计算机-集海卫通 | 涡流探伤仪-超声波探伤仪-上海仓信电子科技有限公司 | 龙淼环保-旋流-喷淋塔,高温布袋,脉冲布袋-单机-滤筒除尘器,活性炭吸附箱,催化燃烧设备,除尘器配件-沧州龙淼环保设备制造有限公司 | 减速电机-调速电机-四大系列减速机-减速电机厂家-深圳市鑫希田机电有限公司官网 | 廊坊纳科新材料技术有限公司--纳科新材料技术有限公司|廊坊纳科新材料|纳科新材料技术 | 呕吐毒素快速检测仪-黄曲霉毒素测定仪-玉米赤霉烯酮快速检测卡-南京微测生物科技有限公司 | 山东中橡新材料有限公司-专业色素炭黑厂家-生产销售各种色素炭黑-用途广泛-价格优势-供应稳定 | 上海慧泰仪器制造有限公司_一体型马弗炉-可控真空干燥箱-强光稳定性试验箱 | 青浦区摄像头安装/青浦区无线网络覆盖/青浦区网络调试公司/青浦区IT外包公司/金山区网络维护公司/金山区防火墙调试公司 | 湖北大洋塑胶有限公司|AGR|PPR|RTP|HDPE|e-PSP钢塑复合压力管道生产厂家 |