我把JavaScript在瀏覽器中運行主要分爲如下幾種類型的任務:javascript
具體流程:html
demo1.htmljava
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo1:宏任務(MacroTask)和微任務(MicroTask)執行順序</title> </head> <body> <script type="text/javascript"> console.log('同步任務1 start'); setTimeout(function () { console.log('宏任務1:setTimeout...'); }, 0); Promise.resolve().then(function () { console.log('微任務1 Promise.then() 1') }).then(function () { console.log('微任務2 Promise.then() 2') }); setTimeout(function () { console.log('宏任務2:setTimeout...'); Promise.resolve().then(function () { console.log('宏任務2:setTimeout => 微任務 Promise.then()') }); }, 0); setTimeout(function () { console.log('宏任務3:setTimeout...'); }, 0); Promise.resolve().then(function () { console.log('微任務3 Promise.then() 1') }).then(function () { console.log('微任務3 Promise.then() 2') }) console.log('同步任務2 end'); </script> </body> </html>
運行結果:git
以上代碼詳細的運行步驟隊列圖,我已經寫成了PPT,你們能夠下載打開看效果,能夠詳細瞭解每一段代碼在隊列中的樣子:github
https://github.com/Jameswain/...segmentfault
setInterval其實能夠說是setTimeout的語法糖,由於setInterval可以實現的功能,setTimeout也能實現,下面經過一個小例子實現使用setTimeout實現setInterval的定時調度功能:瀏覽器
function logic() { console.log(Date.now()); setTimeout(logic, 1000); } logic();
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>demo1:setTimeout與setInterval</title> </head> <body> <div class="demo">demo</div> <script type="text/javascript"> console.log('同步任務1 start'); setInterval(() => { console.log('宏任務1:setInterval...'); Promise.resolve().then(function () { console.log('宏任務1:setInterval => 微任務1 Promise.then()') }); Promise.resolve().then(function () { console.log('宏任務1:setInterval => 微任務2 Promise.then()') }); Promise.resolve().then(function () { console.log('宏任務1:setInterval => 微任務3 Promise.then()') }); }, 3000); setTimeout(function () { console.log('宏任務2:setTimeout...'); }, 0); // 微任務:監聽DOM屬性變化,當屬性發生變化時觸發回調函數 const demo = document.querySelector('.demo'); new MutationObserver(() => { console.log('MutationObserver Callback...'); }).observe(demo, { attributes: true }); Promise.resolve().then(function () { console.log('微任務1 Promise.then() 1') Promise.resolve().then(() => { console.log('微任務1-1 Promise.then() 1') }); Promise.resolve().then(() => { console.log('微任務1-2 Promise.then() 2') Promise.resolve().then(() => { console.log('微任務1-2-1 Promise.then() 1') }); }); }); // 修改DOM元素屬性,將回調變化回調函數放入微任務隊列中 demo.setAttribute('data-random', Math.random()); console.log('同步任務2 end'); </script> </body> </html>
運行結果:dom
從運行結果能夠發現,JavaScript的代碼在瀏覽器中的執行順序是【同步任務】 => 【清空微任務隊列】=>【宏任務】=> 【清空微任務隊列】,若是在執行微任務時,又發現了微任務,它會把這個微任務放入到微任務隊列的末尾。宏任務也同樣,若是在執行宏任務的時候發現了宏任務,它也會把這個宏任務放入宏任務隊列的末尾。函數
上代碼詳細的運行步驟隊列圖,我已經寫成了PPT,你們能夠下載打開看效果,能夠詳細瞭解每一段代碼在隊列中的樣子:oop
https://github.com/Jameswain/...
參考文檔:
Tasks, microtasks, queues 和 schedules