javaScript事件循环机制
一、背景知识
浏览器是多进程的,每个tab页代表一个独立的进程;
浏览器包含的线程有:GUI渲染线程、JS引擎线程、事件触发线程、定时器触发线程、http请求线程等
二、执行中的线程
主线程:js引擎的执行线程,线程只有一个,负责页面渲染、函数处理等
工作线程:幕后线程,可能存在于浏览器或js引擎内,与主线程分开,处理文件读取、网络请求等异步事件。
任务队列:所有的任务可以分为同步任务和异步任务;
同步任务:立即执行,直接进入主线程中执行;
异步任务:通过任务队列机制(先进先出机制)来协调;
三、事件循环
同步任务进入主线程,异步任务进入任务队列。主线程内的任务执行完毕,会去任务队列读取对应的任务,推入主线程执行,上述过程不断重复就是Event Loop(事件循环);
每一次循环称为一次tick,每一次tick的步骤如下:
1.在tick中选择最先进入队列的任务,如果有则执行
2.检查是否Microtasks,如果存在则不停的执行,直至清空Microtask Queue
3.更新render
4.主线程重复执行上述步骤
宏任务:script整体代码、setTimeOut、setInterval、I/O、UI交互事件、setImmediate(Node.js)
微任务:Promise、MutainonObserver、process.nextTick(Node.js)
四、异步编程与宏任务和微任务
异步编程在浏览器端有点击事件、回调函数、Promise等,Promise是微任务,那么点击事件和回调函数呢?
1.点击事件
<script>
button.addEventListener('click',()=>{
console.log('listener1');
Promise.resolve().then(()=>console.log('micro task1'))
})
button.addEventListener('click',()=>{
console.log('listener2');
Promise.resolve().then(()=>console.log('micro task2'))
})
button.click(); // click1() click2()
</script>
运行发现:当直接打开页面不点击时,点击事件为微任务,运行结果为:
listener1
listener2
micro task1
micro task2
当点击按钮时,点击事件为宏任务,运行结果为:
listener1
micro task1
listener2
micro task2
2.回调函数
回调函数分为同步回调和异步回调,同步回调如下,会同步执行回调。
arr.forEach(item=>{
console.log(item)
})
异步回调才需要区分宏任务还是微任务。
本文地址:https://blog.csdn.net/wangzheweini/article/details/107320535
上一篇: 新鲜出炉的前端面经
下一篇: 洛谷 P1303 高精度乘高精度