eventLoop的概念
其实浏览器有很多线程,比如有js引擎线程,有事件触发器线程,网络请求线程,定时器线程,当js引擎处理到设计其他的线程的时候,比如有个异步请求,比如有个click事件绑定,比如有定时器,或者有了要更改dom的操作。当有了涉及其他线程的代码执行时候,浏览器会分配给相应的线程去执行,比如去请求,比如去等待被点击,比如去定时器读秒…当相应的事件或者说回调的条件被触发时,回调函数的执行代码会被塞到任务队列里最后,等待js引擎处理。但是注意gui渲染线程和js引擎是互斥的 一个时间只能一个在执行。
我们来举一些例子,
1 document.addEventListener("nihao",nihaoHandler); 2 3 console.log("aaa"); 4 5 document.dispatchEvent(new Event("nihao")); 6 7 console.log("bbb"); 8 9 10 function nihaoHandler(){ 11 console.log("ccc"); 12 } 13 // 输出结果 aaa ccc bbb
事件的触发是一个异步过程,而事件本身是同步,因此我们一抛发事件,打印ccc会立刻执行。
宏任务、微任务
微任务: Promise 、async函数、 await
宏任务: setTimeout、setInterval
宏任务与微任务的区别:
微任务是将当前内容放在当前任务列的最底端
宏任务是将当前内容放在下一个任务列的最顶端
当一个宏任务和一个微任务并列时,微任务永远比宏任务先执行
// 宏任务 setTimeout(function(){ console.log("bbb"); },0); // 微任务 Promise.resolve().then(function(){ console.log("ccc"); }); // 输出结果 ccc bbb
当一个宏任务嵌套一个微任和一个微任务里面嵌套一个宏任务并列时,宏任务里面的微任务会比微任务里面的宏任务先执行
1 // 宏任务 2 setTimeout(function(){ 3 Promise.resolve().then(function(){ 4 console.log("bbb"); 5 }) 6 },0) 7 // 微任务 8 Promise.resolve().then(function(){ 9 setTimeout(function(){ 10 console.log("aaa"); 11 },0) 12 }); 13 // 输出结果 bbb aaa