對於執行時間過長的腳本,有的瀏覽器會彈出警告,說頁面無響應。有的瀏覽器會直接終止腳本。總而言之,瀏覽器不但願某一個代碼塊長時間處於運行狀態,由於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左右。這就不會引發頁面卡頓等問題。
異步