巧用setTimeout解決阻塞導致頁面無法重繪


項目中遇到一個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示例能理解也能正確的運行,但是放在項目中,並沒有效果。好在通過其他方法暫時解決了,不過這不是本文的重點了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM