任务队列与事件循环
JS是单线程,为了防止线程的阻塞,在代码执行时分为同步任务和异步任务。所有同步任务在主线程上执行,推入栈中执行,当执行栈为空时就回去去事件队列中执行异步任务,而异步任务形成一个新的任务队列,任务队列中的异步任务分为宏任务和微任务,任务队列中微任务的优先级大于宏任务。
什么是任务队列
简言之,JS任务分为同步任务和异步任务,同步代码在栈中同步执行,其中异步任务又分为宏任务和微任务,微任务执行执行完后才会执行宏任务。
另外这里的执行栈与存储数据类型的栈的概念是不同的,JS代码执行时会生成执行上下文(执行环境)。JS代码执行过程中不停的将执行上下文压入栈中,遵循先进后出。
什么是事件循环
不进入主线程,而是进入任务队列,当主线程中的任务执行完毕,就从任务队列中取出任务放进主线程中来进行执行。由于主线程不断重复的获得任务、执行任务、再获取再执行,所以者种机制被叫做事件循环(Event Loop)
宏任务
浏览器为了能够使得JS内部任务与DOM任务能够有序的执行,会在一个任务执行结束后,在下一个任务执行开始前,对页面进行重新渲染
常见的宏任务有 定时器,ajax,读取文件,dom事件,setImmediate(Node.js 环境),requestAnimationFrame,I/0,UI交互,postMessage
微任务
微任务(microtask)是宏任务中的一个部分,它的执行时机是在同步代码执行之后,下一个宏任务执行之前。
常见的微任务有,Promise.then,Object.observe,MutationObserver,process.nextTick(Node.js 环境)
任务执行过程
-
所有任务都在主进程上执行,异步任务会经历2个阶段 Event Table和Event Queue
-
同步任务在主进程排队执行,异步任务(包括宏任务和微任务)在事件队列排队等待进入主进程执行
-
遇到宏任务推进宏任务队列,遇到微任务推进微任务队列
-
执行宏任务,执行完宏任务,检查有没有当前层的微任务。
-
继续执行下一个宏任务,然后执行对应层次的微任务,直到全部执行完毕。