我把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