做者:葉@毛豆前端javascript
js的事件循环机制,在我理解起来就是执行上下文,对函数的出栈和入栈的一个过程。都知道js的一大特色是单线程,这也是这个语言的核心特征。试想一下,若是js是个多线程的语言,同时存在两个线程,一个线程是在某个Dom上添加节点,而另外一个线程倒是删除节点,这个时候浏览器就会产生错乱,而咱们关心的js事件循环机制,正是由js的单线程特质决定的。前端
先上图,看下大体流程java
涉及的到异步进程:git
知道了js的大体执行的过程了,咱们看下其中涉及到的一些概念github
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅容许在表的一端进行插入和删除运算ajax
function fun2() {
console.log('fun2')
}
function fun1() {
fun2();
}
setTimeout(() => {
console.log('setTimeout')
})
fun1();
复制代码
以上的出入栈如图所示浏览器
js中存在着多个任务队列,而且不一样的任务队列之间优先级不一样,优先级高的先被获取。同一队列中按照队列顺序被取用 任务队列分为两种类型数据结构
二者的区别:多线程
事实上,事件循环的顺序,决定了JavaScript代码的执行顺序。执行时从script(总体代码)开始第一次循环,以后全局上下文进入函数调用栈,直到执行栈清空,而后开始执行全部的microtask,当全部可执行的micro-task执行完毕以后。循环再次从macro-task开始,找到其中一个任务队列执行完毕,而后再执行全部的micro-task,这样一直循环下去。事件循环每次只会入栈一个 macrotask ,主线程执行完该任务后又会先检查 microtasks 队列并完成里面的全部任务后再执行 macrotask。异步
咱们举个例子验证下吧:
console.log('-----start-----')
setTimeout(()=>{
console.log('setTimeout1-macroTask')
},1000)
Promise.resolve().then(() => {
console.log('Promise1-microTask')
});
Promise.resolve().then(() => {
console.log('Promise2-microTask')
});
setTimeout(()=>{
console.log('setTimeout2-macroTask')
},100)
console.log('-----end-----')
输出结果
-----start-----
-----end-----
Promise1-microTask
Promise2-microTask
setTimeout2-microTask
setTimeout1-microTask
复制代码
具体过程,咱们稍微归纳下: