setTimeout和異步隊列

```

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

if(i===1){

setTimeout(function(){console.log("timeout")},0)

}

console.log(i)

}

```

當真正運行的時候你會發現,這個"timeout"文字會在整個for執行完之後再執行,而不是想當然的在某一步運行完之後執行。


setTimeout/setInterval

DOM事件,有時候點擊事件會卡死,就是因爲當前js正在處理,無法將click觸發事件放入執行棧

Promise也是異步隊列


JS的異步機制由事件循環和任務隊列構成.JS本身是單線程語言,所謂異步依賴於瀏覽器或者操作系統等完成. JavaScript 主線程擁有一個執行棧以及一個任務隊列,主線程會依次執行代碼,當遇到函數時,會先將函數入棧,函數運行完畢後再將該函數出棧,直到所有代碼執行完畢。


遇到異步操作(例如:setTimeout, AJAX)時,異步操作會由瀏覽器(OS)執行,瀏覽器會在這些任務完成後,將事先定義的回調函數推入主線程的任務隊列(task queue)中,當主線程的執行棧清空之後會讀取task queue中的回調函數,當task queue被讀取完畢之後,主線程接着執行,從而進入一個無限的循環,這就是事件循環.


JavaScript是單線程執行的,無法同時執行多段代碼。當某一段代碼正在執行的時候,所有後續的任務都必須等待,形成一個隊列。一旦當前任務執行完畢,再從隊列中取出下一個任務,這也常被稱爲 “阻塞式執行”。所以一次鼠標點擊,或是計時器到達時間點,或是Ajax請求完成觸發了回調函數,這些事件處理程序或回調函數都不會立即運行,而是立即排隊,一旦線程有空閒就執行。假如當前 JavaScript線程正在執行一段很耗時的代碼,此時發生了一次鼠標點擊,那麼事件處理程序就被阻塞,用戶也無法立即看到反饋,事件處理程序會被放入任務隊列,直到前面的代碼結束以後纔會開始執行。如果代碼中設定了一個 setTimeout,那麼瀏覽器便會在合適的時間,將代碼插入任務隊列,如果這個時間設爲 0,就代表立即插入隊列,但不是立即執行,仍然要等待前面代碼執行完畢。所以 setTimeout 並不能保證執行的時間,是否及時執行取決於 JavaScript 線程是擁擠還是空閒。

發佈了39 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章