項目中遇到一個javascript問題,大致如下:
<!doctype HTML> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <div>0</div> <a href="#">按鈕</a> <script> $(function () { function myFun() { //dosomething } $("a").click(function () { $("div").text(1);//代碼執行,但GUI線程還未處理,代碼就執行下一行 myFun();//很耗時的方法,執行了30s,整個頁面阻塞 $("div").text(100); }); }); </script> </body> </html>
嘗試各種辦法無解,就學習了javascript單線程,以尋求解決辦法。
看到Javascript是單線程的深入分析這篇博文時候,增長了知識,也獲取到解決辦法。
代碼示例:
<!doctype html> <html> <head> <meta charset="utf-8" /> <title>setTimeOut(fun,0)</title> </head> <body> <button id='do'> Do long calc!</button> <div id='status'></div> <script src="http://cdn.bootcss.com/jquery/1.8.2/jquery.min.js"></script> <script> $('#do').on('click', function () { $('#status').text('calculating....'); //此處會觸發redraw事件的fired,但會放到隊列里執行,直到long()執行完。 // without set timeout, user will never see "calculating...." //long();//執行長時間任務,阻塞 // with set timeout, works as expected setTimeout(long, 50);//用定時器,大約50ms以后執行長時間任務,放入執行隊列,但在redraw之后了,根據先進先出原則 }) function long() { var result = 0 for (var i = 0; i < 1000; i++) { for (var j = 0; j < 1000; j++) { for (var k = 0; k < 1000; k++) { result = result + i + j + k } } } $('#status').text('calclation done'); } </script> </body> </html>
更多參考文章:http://www.codeceo.com/article/javascript-threaded.html
PS:Demo示例能理解也能正確的運行,但是放在項目中,並沒有效果。好在通過其他方法暫時解決了,不過這不是本文的重點了。