为什么Js会有事件循环机制
js是单线程 非阻塞 脚本 语言,js代码在执行时,只有一个主线程来处理的任务,非阻塞靠的就是(异步执行)事件循环(Event Loop)。
事件循环——微任务、宏任务
大家都知道的js大概的执行顺序是自上而下,可分为同步任务和异步任务,其实在细分一下就是 主线程执行同步任务,异步任务放到了宏任务(macro-task)或 微任务(micro-task)的队列中,等主线程空了就会读取任务队列,这就是js的运行机制也就是事件循环(EventLoop),简单点说eventloop就是在处理异步行为的过程。
宏任务
- 整个script:可以把整个script 或一个js文件看成单个大的宏任务
- setTimeout 和 setInterval:这两个函数用于定时操作,它们会创建一个宏任务队列,当定时器时间到达时,宏任务就会被移到执行队列
- setImmediate:这是一个Node.js环境下的宏任务,工作原理类似于setTimeout,但是它将在当前事件循环的末尾立即执行
- I/O 操作:所有与系统交互的操作,如读写文件、读写数据库、HTTP请求等,都属于宏任务
- UI渲染:当浏览器完成页面布局并将元素呈现在屏幕上时,也会创建一个宏任务
微任务
- Promise:Promise对象代表一个异步操作的最终完成(或失败)及其结果值。当异步操作完成时,Promise就会被解决(resolve)或拒绝(reject)。
- Object.observe:Object.observe() 方法用于将一个对象添加到观察列表中,以便在对象改变时接收通知
- MutationObserver:MutationObserver接口提供了监视DOM树更改的能力,这样可以在任何DOM树更改发生时运行特定的代码
- process.nextTick:在Node.js环境下,process.nextTick() 用于在I/O事件到来之前,将回调函数放到当前执行栈的末尾
- async/await:async函数返回一个Promise对象,可以使用await操作符来等待异步操作的完成
执行顺序
任务列表内先进先出 先微后宏 微中宏-先微后宏 微中微-按序排 宏中微-先宏后微
举例
例1:
setTimeout(function(){
console.log(1);
});
new Promise(function(resolve){
console.log(2);
resolve();
}).then(function(){
console.log(3);
}).then(function(){
console.log(4)
});
console.log(5);
分析:
- 自上而下执行
setTimeout放入宏任务列表 - 实例化 promise 这是过程是同步任务,直接执行
- 第一个promise.then则是异步中的微任务,放入微任务列表
- 第二个promise.then也是异步中的微任务,放入微任务列表
- 最后的console则是同步任务
最后输出则是 2 5 3 4 1
以上是个人对事件循环的理解如有问题希望大家留言一起探讨
- THE END -
最后修改:2024年6月24日
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:https://mi-blog.cn/index.php/2020/02/05/%e6%b5%85%e8%b0%88js%e4%b8%ad%e7%9a%84event-loop/