JS事件循环,了解一下

在理解事件循环以前,我总会遇到一些奇奇怪怪的问题:好比明明已经调接口拿到了数据,但是跟在调数据以后的操做却没有正常执行;又或者不知道为啥,代码里非得加个setTimeout才能正常跑通;特别是在运用Promise的时候,更是有各类问题百思不得解。赶上问题要解决,更要知道问题产生的缘由,这样才能hold住全场!前端

废话很少说了,先来看一段代码ajax

console.log('start');

setTimeout(function(){
   console.log('setTImeout1') 
},0);

new Promise(function(resolve,reject){
    console.log('resolve')
    setTimeout(function(){
        console.log('setTimeout2')
    },200);
    resolve()
}).then(function(){
    console.log('then')
});

setTimeout(function(){
    console.log('setTimeout3')
},0);

console.log('end');

结果是start resolve end then setTimeout1 setTimeout3 settimeout2数据结构

在分析结果以前,我先来科普几个概念,这些概念的表述不必定与标准彻底对应,可是能够帮助你更容易理解JS的事件机制异步

  • 宏任务(macro-task):包括js总体代码,setTimeout,setInterval,setImmediate ,I/O, UI renderder等
  • 微任务(micro-task):包括Promise,Object.observe,process.nextTick,MutationObserver等
  • 调用栈:js被加载进来以后,会从上至下读取代码,同步代码被当即执行,而异步代码被加入事件队列中
  • 事件队列:一些没有被当即执行的代码被添加到事件队列中,队列是一种先进先出的数据结构,也就是说,先加入事件队列的任务会被优先执行

咱们知道,js是单线程的,这就是说,只有一个主线程,主线程会自上而下依次执行调用栈中的事件。任务队列中的代码被加载到函数调用栈中去执行。当前的宏任务队列中的代码执行完毕后,会执行本次宏任务队列中分发到微任务队列中的代码。而后执行下一个宏任务队列中的代码,依次循环。函数

这里要提一点容易误解的地方,setTimeout函数自己,实际上是当即执行的,它内部的任务,才会被分发到任务队列中延时执行。spa


  • 代码被加载后,全局上下文进入函数调用栈,紧接着,‘start’被执行
  • 遇到setTimeout的时候,新建了一个宏任务队列,函数内的任务被分发这个队列中等待执行
  • 此时遇到了Promise,注意,Promise中的第一个function中的代码会立马开始执行,遇到resolve或者reject后,then方法中函数会被分发到本次事件循环的微任务队列中等待执行。因此这里立马打印出了'resolve'。遇到setTimeout2后,一样新建了一个宏任务队列,其中的函数被分发到了这个新的宏任务队列中,then方法中的操做被分发到了微任务队列中等待
  • 代码继续往下,遇到'setTimeout3'后再次新建了一个新的宏任务队列
  • 'end'被当即执行。此时有三个宏任务队列,一个微任务队列
  • 微任务队列中的操做被执行,也就是打印出了‘then’,此时,第一轮的事件循环结束。
  • 第一轮的事件循环结束,开始下一轮的事件循环,依次执行每一个宏任务队列中的内容,咱们这里宏任务队列中的函数比较简单,都是console操做,因此并无再分发新的任务队列,可是因为第二个setTimeout设定了200毫秒的延时,因此‘setTimeout2’被最后打印。

说到这里,你基本上对事件循环有个大体的了解了。以前有个同窗问过我一个问题,点击轮播图下一页,可是页面没有反应,代码是这样的:线程


这个函数是点击下一页的按钮后轮播图转动,他在getNextPhoto函数中调接口获取了下个页面的数据,goToPage函数里是让轮播图切换的操做。相信若是你读懂了这篇文章,就会知道问题出在了哪里。显然获取数据ajax是个异步操做,他被分发到了事件队列中等待执行,因此还没等数据回来,翻页的操做已经开始执行,因为没有数据,并无按预期效果显示。解决方法就是在getNextPhoto函数里调接口拿到数据以后,再通知去执行goToPage操做,问题就解决了。code

做为一个前端菜鸟,但愿获得各位大神的批评指正!server

相关文章
相关标签/搜索