对于执行时间过长的脚本,有的浏览器会弹出警告,说页面无响应。有的浏览器会直接终止脚本。总而言之,浏览器不但愿某一个代码块长时间处于运行状态,由于js是单线程的。一个代码块长时间运行,将会致使其余任何任务都必须等待。从用户体验上来讲,颇有可能发生页面渲染卡顿或者点击事件无响应的状态。javascript
若是一段脚本的运行时间超过5秒,有些浏览器(好比Firefox和Opera)将弹出一个对话框警告用户该脚本“没法响应”。而其余浏览器,好比iPhone上的浏览器,将默认终止运行时间超过5秒钟的脚本。--《JavaScript忍者秘籍》
JavaScript忍者秘籍里有个很好的比喻:页面上发生的各类事情就好像一群人在讨论事情,若是有我的一直在说个不停,其余人确定不乐意。咱们但愿有个裁判,定时的切换其余人来讲话。html
Js利用定时器来分解任务,关键点有两个。java
要求:动态建立一个表格,一共10000行,每行10个单元格浏览器
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <table> <tbody></tbody> </table> <script type="text/javascript"> var tbody = document.getElementsByTagName('tbody')[0]; var allLines = 10000; // 每次渲染的行数 console.time('wd'); for(var i=0; i<allLines; i++){ var tr = document.createElement('tr'); for(var j=0; j<10; j++){ var td = document.createElement('td'); td.appendChild(document.createTextNode(i+','+j)); tr.appendChild(td); } tbody.appendChild(tr); } console.timeEnd('wd'); </script> </body> </html>
总共耗时180ms, 浏览器已经给出警告![Violation] 'setTimeout' handler took 53ms
。app
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> </head> <body> <table> <tbody></tbody> </table> <script type="text/javascript"> var tbody = document.getElementsByTagName('tbody')[0]; var allLines = 10000; // 每次渲染的行数 var everyTimeCreateLines = 80; // 当前行 var currentLine = 0; setTimeout(function renderTable(){ console.time('wd'); for(var i=currentLine; i<currentLine+everyTimeCreateLines && i<allLines; i++){ var tr = document.createElement('tr'); for(var j=0; j<10; j++){ var td = document.createElement('td'); td.appendChild(document.createTextNode(i+','+j)); tr.appendChild(td); } tbody.appendChild(tr); } console.timeEnd('wd'); currentLine = i; if(currentLine < allLines){ setTimeout(renderTable,0); } },0); </script> </body> </html>
此次异步按批次建立,没有耗时的警告。由于控制了每次代码在50ms内运行。实际上每80行耗时约10ms左右。这就不会引发页面卡顿等问题。
异步