javascript一門單線程的非阻塞的腳本語言。當用戶進行點擊元素,又進行元素移除,這樣就會致使哪一個事件的優先級不知道,因此JS必須是單線程的。爲了協調事件,用戶交互,腳本,UI渲染,和網絡處理,Event Loop能夠防止主線程阻塞。在某些花費時間較長的事件,瀏覽器會將它們掛起(pending),事件等待被執行,事件循環是經過任務隊列實現的。javascript
one thread == one callback == one thing at a time.java
棧是一種遵循後進先出(LIFO)的數據集合,新添加或待刪除的元素都保存在棧的末尾,稱做棧頂,另外一端稱做棧底。在棧裏,新元素都靠近棧頂,舊元素都靠近棧底web
隊列是一種遵循先進先出(FIFO)的數據集合,新的條目會被加到隊列的末尾,舊的條目會從隊列的頭部被移出。ajax
能夠這樣理解,有兩個隊列—— 執行隊列(同步任務synchronous)、事件隊列(異步任務asynchronous),存放全部着JS執行的任務(ajax、點擊事件、UI渲染等、promise.then)。promise
運行Js代碼,從上往下執行代碼,同步代碼,依次執行,遇到異步代碼,則根據其任務類型,添加到相應的對應隊列,宏任務放入事件隊列,微任務放於執行隊列以後(可是會是某個事件循環的最後),事件隊列(任務)以前。這個處理事件過程是不斷循環的,只要主線程空了,就會去讀取"任務隊列"而且執行。瀏覽器
<script>
console.log('script start');
setTimeout(function() {
console.log('timeout1');
}, 0);
new Promise(resolve => {
console.log('promise1');
resolve();
setTimeout(() => {
console.log('timeout2');
new Promise(resolve => {
resolve();
}).then(function() {
console.log('then3')
})
}, 0);
}).then(function() {
console.log('then1')
})
new Promise(resolve => {
resolve();
}).then(function() {
console.log('then2')
})
console.log('script end');
</script>
複製代碼