任務隊列
主線程:正在執行的代碼,會生成函數調用棧。
任務分類
同步任務,語句只按語句先后順序執行,前面未執行完,不會執行后面語句。
異步任務,語句不在語句先后順序上執行,執行到該代碼時,加入到相應任務隊列,延后執行。
單線程
主線程從 script (整體代碼)開始第一次循環。之后全局上下文進入函數調用棧。直到調用棧清空(只剩全局),然后執行所有的 jobs。當所有可執行的 jobs 執行完畢之后。循環再次從 task 開始,找到其中一個任務隊列執行完畢,然后再執行所有的 jobs,這樣一直循環下去。
注意事項
經典示例
示例詳解:https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/
通過鼠標點擊
<div class="outer"> <div class="inner"></div></div>// Let's get hold of those elementsvar outer = document.querySelector('.outer');var inner = document.querySelector('.inner');// Let's listen for attribute changes on the// outer elementnew MutationObserver(function() { console.log('mutate');}).observe(outer, { attributes: true});// Here's a click listener…function onClick() { console.log('click'); setTimeout(function() { console.log('timeout'); }, 0); Promise.resolve().then(function() { console.log('promise'); }); outer.setAttribute('data-random', Math.random());}// …which we'll attach to both elementsinner.addEventListener('click', onClick);outer.addEventListener('click', onClick);// 輸出結果clickmutateclickmutatepromisepromisetimeouttimeout
進階--通過js執行
<div class="outer"> <div class="inner"></div></div>// Let's get hold of those elementsvar outer = document.querySelector('.outer');var inner = document.querySelector('.inner');// Let's listen for attribute changes on the// outer elementnew MutationObserver(function() { console.log('mutate');}).observe(outer, { attributes: true});// Here's a click listener…function onClick() { console.log('click'); setTimeout(function() { console.log('timeout'); }, 0); Promise.resolve().then(function() { console.log('promise'); }); outer.setAttribute('data-random', Math.random());}// …which we'll attach to both elementsinner.addEventListener('click', onClick);outer.addEventListener('click', onClick);inner.click();// 輸出結果clickclickmutatepromisepromisetimeouttimeout
由于點擊事件是 js 執行的,inner 的 onClick 函數執行完成時,inner.click() 語句的作用域還沒有退棧,主線程調用棧不是空的,導致 jobs 隊列任務不會執行,mutate 和 promise 語句都未能在事件循環中執行到。從而執行了 outer 的 onClick 函數。outer 的 onClick 函數執行完成后,inner.click() 語句才退棧,繼而執行 jobs 的任務。
只有一個 mutate 是由于 jobs 隊列中,只能有一個 MutationObserver 任務,第二次創建時,前一個 MutationObserver 任務沒有執行,顧不再創建。
總結
以上所述是小編給大家介紹的JS內部事件機制之單線程原理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
新聞熱點
疑難解答