JavaScipt 中的事件循环(event loop),以及微任务 和宏任务的概念

 说事件循环(event loop)之前先要搞清楚几个问题。

1. js为什么是单线程的?
  试想一下,如果js不是单线程的,同时有两个方法作用dom,一个删除,一个修改,那么这时候浏览器该听谁的?这就是js被设计成单线程的原因。
 
2.js为什么需要异步?
  如果js不是异步的话,由于js代码本身是自上而下执行的,那么如果上一行代码需要执行很久,下面的代码就会被阻塞,对用户来说,就是”卡死”,这样的话,会造成很差的用户体验。
 
3.js是如何实现异步的?
  既然js是单线程的,那么js是如何实现异步的呢,是通过事件循环(event loop),理解了event loop 就理解了js的执行机制。
 
4.浏览器中的多线程?
  js是单线程的,但是浏览器是多线程的,多个线程相互配合以保持同步,浏览器下的常驻线程有
  • js线程
  • GUI渲染线程,(它与javaScript线程是互斥的)
  • 事件线程(onclick,onchange,…)
  • 定时器线程(setTimeout, setInterval)
  • 异步http线程(ajax)
 
5. javaScript 的事件循环(event loop
既然js是单线程的,那么所有的任务就需要排队执行。
  • javaScript 中的任务可以被划分为宏任务(Macrotask)或者微任务(Microtask)
  • 像鼠标事件,键盘事件,"ajax","setTimeout"等就属于宏任务,需要注意的是,主线程的整体代码(script标签),也是一个宏任务
  • process.nextTick,PromiseA.then(), MutaionObserver 就属于微任务
简单概括一下事件循环,就是
1.执行宏任务队列中第一个任务,执行完后移除它
2.执行所有的微任务,执行完后移除它们
3.执行下一轮宏任务(重复步骤2)
如此循环就形成了event loop,其中,每轮执行一个宏任务所有的微任务
 
下图很形象的描述了event loop
 
网上有用异步任务和同步任务来说明这个问题的,但是我觉得用宏任务和微任务更好点。
 
下面我通过分析一个示例来说一下:
复制代码
console.log(1);  setTimeout(function(){     console.log(2) },10);  new Promise(function(resolve){     console.log(3)     for( var i=100000 ; i>0 ; i-- ){         i==1 && resolve()     }     console.log(4) }).then(function(){     console.log(5) }).then(function(){ 
console.log(6)
})
console.log(
7);
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信