setTimeout的異步


有時候,加載一些廣告的時候,我們用setTimeout實現異步,好讓廣告不會阻塞我們頁面的渲染。 

為什么setTimeout能夠實現異步呢?
 
看一段糟糕的代碼:
setTimeout(function() {
        while (true) {
        }
}, 100);
setTimeout(function() {
        alert('你好!');
}, 200);
 
setTimeout是異步,那么,不管前面的代碼怎么樣,他條件滿足了就會執行,但上面的代碼,由於任務隊列里有一個死循環,而后面的彈出代碼在隊列的后面,循環不息,所以后面的永遠不會被執行到。
 
理解setTimeout,我個人認為就是理解瀏覽器的執行模型。
 
瀏覽器是基於一個事件循環的模型,在這里面,可以有多個任務隊列, 比如render是一個隊列,響應用戶輸入是一個,script執行是一個。 任務隊列里放的是任務,同一個任務來源的任務肯定在同一個任務隊列里。
任務有優先級,鼠標或鍵盤響應事件優先級高,大概是其他任務的3倍。
 
任務的執行過程中可能產生:
spin:不影響Event Loop並延后執行
pause:停止Event Loop並延后執行
 
spin,如setTimeout的異步方式,就是spin方式,當執行到setTimeout時,此任務先暫停並保存,繼續執行后續任務,當條件滿足時,再將setTimeout的執行任務放回任務隊列的后面,等待執行,假如前面有一個2s的任務,那原本是delay 1s的任務實際執行時會是在第3s的時候才執行。
 
pause,則是當在js中獲取元素的offsetWidth等需要更新dom操作的動作時發生的。當執行到此任務時,將停止事件循環的工作,也就是先停止js引擎解析執行,跳到渲染引擎更新用戶界面至當前狀態,這期間,不處理后續任務,當前執行的腳本暫停,界面保持響應,但無法處理輸入(事件循環停了),直到成功返回才繼續執行任務。
 
setTimeout的技巧使用:
 
1 <input type="text" value="a" name="input" onkeydown="alert(this.value)" />
2 <input type="text" value="a" name="input"
3 onkeydown="var me=this;setTimeout(function(){alert(me.value)},0)" />
 
第一個在keydown的時候,彈出來的是input里原來的value,而第2個在keydown的時候,卻能彈出更新后的value,就是因為setTimeout,雖然他的delay設置為0,幾乎是即時觸發,但還是被添加到了執行隊列后面,但就是這個過程,渲染已經完成了,當他回調函數執行時,輸出來的已經是更新后的value了。
 
setTimeout知識點的面試題:
 
下面的代碼,多久之后會彈出'end'? 為什么?
 
1 var t = true;
2  
3 setTimeout(function(){ t = false; }, 1000);
4  
5 while(t){ }
6  
7 alert('end');
 
答案明顯,都在上面有解釋到了。
 
參考文章:
 
 


免責聲明!

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



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