從setTimeout到瀏覽器線程機制 ,實現JS線程和UI同時執行的效果


遇到一個問題情況:

ocx讀取多條記錄的結果集。

在js里用 for遍歷。

for(var i= 0;i<length;i++){

     $.ajax({

       后台返回結果

       處理成功,

       調用更新進度條的方法。

     })

}

發現,總是當for全部遍歷完成,才去渲染進度條控件。更改樣式。

查閱N多資料更改后,

將for改為遞歸調用,沒執行一次,渲染一次進度條,后面的JS代碼放在setTimeout(function,0),這時瀏覽器會優先渲染UI界面,然后在執行后面的JS代碼,就實現了進度條實時更新了。

 

 

//更新進度條的數據
run(size,a+1);
if(a<size-1){
++a;
//讓JS線程等待100,等待會讓UI渲染進程實現
setTimeout(submitData,10);
//submitData();
}else{
size = 0;
a= 0;
return ;
}

解決問題知識點:從setTimeout到瀏覽器線程機制 

我們知道瀏覽器內部至少會有這么兩個線程:解析js的線程和渲染界面的線程。這里我們暫且稱它們為JS線程和UI線程。

由於js是可操縱DOM的,如果在修改這些元素屬性同時渲染界面(即JS線程和UI線程同時運行),那么渲染線程前后獲得的元素數據就可能不一致了。因此為了防止渲染出現不可預期的結果,瀏覽器控制JS線程和UI線程以列隊的形式同步執行。

setTimeout執行時會新開一個定時器線程,這是正好處於JS線程運行當中,當JS線程執行完成后,發現setTimeout馬上就要開始執行(即時間小於上述的臨界值),為了避免UI線程運行時間太長而帶來的setTimeout嚴重拖時的不好體驗,瀏覽器選擇一直等待直到setTimeout到期,然后運行里面的js。如果發現setTimeout還要隔較長時間才到期,為了避免時間上的浪費,瀏覽器選擇馬上切換到UI線程。 

結論:setTimeout 可用於處理耗時的js代碼,但千萬要小心第二個參數不要設置太小了,否則你看到的同樣是一個空白頁面。推薦在100ms左右,可滿足所有瀏覽器。當然,如果可以不兼容IE的話,拋棄setTimeout吧,web workers 會是個很好的選擇。


免責聲明!

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



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