先上一段代碼,能夠根據本身以前對JS執行機制的理解,進行分析promise
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
答案:
script start
script end
promise1
promise2
setTimeout異步
若是本身的答案和上面的答案有出入,請繼續閱讀函數
調用堆棧動畫
事件表spa
事件隊列code
在當前的微任務沒有執行完成時,是不會執行下一個宏任務的。
這裏有兩種說法,一種說法把剛開始執行的總體JS代碼認爲是一個宏任務,先執行總體JS代碼這一個宏任務,執行完成後,再執行微任務列表中的全部微任務,因此認爲先執一個行宏任務再執行全部微任務隊列
另一種說法沒有把剛開始的JS代碼當作宏任務,因此起始執行的是微任務,全部微任務執行完再執行宏任務,認爲先執行微任務再執行宏任務
其實兩種說法的核心是同樣的,都是執行一個宏任務 執行全部微任務
事件循環進程
console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0); Promise.resolve().then(function() { console.log('promise1'); }).then(function() { console.log('promise2'); }); console.log('script end');
再次分析此段代碼
最初始狀態:JS調用棧爲空,任務隊列中宏任務隊列有script代碼塊就緒
第一步:檢查調用棧爲空,將宏任務script入棧,開始向下執行
第二步:當遇到異步操做時,執行異步,並將異步事件與其回調函數註冊到事件列表,同步代碼繼續執行
第三步:當事件表監聽到異步事件已經完成,將其事件的回調函數入隊(任務隊列)
第四步:檢查到調用棧爲空,先將微任務依次入棧(調用堆棧)執行,微任務列表爲空時,將宏任務入棧(調用堆棧)執行
更多關於JS執行機制的理解請點擊下面連接,有動畫效果有助於理解 特別推薦
Tasks, microtasks, queues and schedules事件