js事件循环机制(Event Loop)
javascript从诞生之日起就是一门 单线程的 非阻塞的 脚本语言,单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务,非阻塞靠的就是 event loop(事件循环),本文就讲解下事件循环。
event loop它最主要是分三部分:主线程、宏队列(macrotask)、微队列(microtask)
js的任务队列分为同步任务和异步任务,所有的同步任务都是在主线程里执行的,异步任务可能会在macrotask或者microtask里面
主线程
就是访问到的script标签里面包含的内容,或者是直接访问某一个js文件的时候,里面的可以在当前作用域直接执行的所有内容(执行的方法,new出来的对象等)
宏队列(macrotask)
setTimeout、setInterval、setImmediate、I/O、UI rendering
微队列(microtask)
promise.then、process.nextTick
执行顺序
1、先执行主线程
2、遇到宏队列(macrotask)放到宏队列(macrotask)
3、遇到微队列(microtask)放到微队列(microtask)
4、主线程执行完毕
5、执行微队列(microtask),微队列(microtask)执行完毕
6、执行一次宏队列(macrotask)中的一个任务,执行完毕
7、执行微队列(microtask),执行完毕
8、依次循环。。。
看下面代码练习练习
console.log(1)
process.nextTick(() => {
console.log(8)
setTimeout(() => {
console.log(9)
})
})
setTimeout(() => {
console.log(2)
new Promise(() => {
console.log(11)
})
})
requestIdleCallback(() => {
console.log(7)
})
// 特殊说明: new Promise()属于主线程任务
let promise = new Promise((resolve,reject) => {
setTimeout(() => {
console.log(10)
})
resolve()
// 这个console也属于主线程任务
console.log(4)
})
fn()
console.log(3)
promise.then(() => {
console.log(12)
})
function fn(){
console.log(6)
}
结果是1、4、6、3、12、8、2、11、10、9、7
这个写法可以囊括80%以上的event loop循环机制的场景了,下面开始梳理具体的运行机制。
js是从上到下执行的,所以上来先打印的是 1 ,继续往下走;
遇见了process.nextTick,因为它属于微队列(microtask),并且当前主线程的代码还没有执行完毕,所以它被展示扔到了微队列里,暂时不打印;
这个时候又遇到了setTimeout,setTimeout是属于宏队列(macrotask);
requestIdleCallback,这里也是不立即执行的,它也不属于任何队列,这里不做详细解释;
promise在实例化的时候,这里的setTimeout继续被丢到了宏队列(macrotask)中,并执行了成功的方法,在有promise.then的调用的时候就会去出发,但这里不做打印,接着发现了console,这里直接打印 4 );
fn函数直接调用,直接打印 6 ;
console,直接打印 3 ;
promise.then因为它属于微队列,但是它在promise实例化的时候被调用了,所以它会在微队列的最前面执行;
到这里主线程里面就没有任何可以执行到东西了,下面开始走微队列(microtask):
由于promise.then被提前调用了,所以它会先执行,打印 12 ;
微队列(microtask)里面还有一个,就是上面的process.nextTick,执行它,打印 8 ,这个时候发现它有一个setTimeout,放到宏队列(macrotask);
到这里微队列就走完了,下面开始走宏队列(macrotask):
最外面的setTimeout在一开始的时候被放了进去,所以先执行它,打印 2 ,发现它里面有promise被实例化,直接执行,打印 11 ;
下一个要走的就是promise里面的setTimeout,打印 10 ;
还剩最后一个setTimeout,就是process.nextTick里面的,打印 9 ;
到这里主线程、宏队列(macrotask)、微队列(microtask)就全都跑完了,在全部跑完的时候,requestIdleCallback才会执行,打印 7 ;
requesIdleCallback会在当前浏览器空闲时期去依次执行,在整个过程当中你可能添加了多个requestIdleCallback,但是都不会执行,只会在空闲时期,去依次根据调用的顺序就执行。
js事件循环机制(Event Loop)的更多相关文章
- Node.js 事件循环(Event Loop)介绍
Node.js 事件循环(Event Loop)介绍 JavaScript是一种单线程运行但又绝不会阻塞的语言,其实现非阻塞的关键是“事件循环”和“回调机制”.Node.js在JavaScript的基 ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)
JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...
- js高级-浏览器事件循环机制Event Loop
JavaScript 是队列的形式一个个执行的 同一时间只能执行一段代码,单线程的 (队列的数据结构) 浏览器是多线程的 JavaScript执行线程负责执行js代码 UI线程负责UI展示的 Jav ...
- 理解js事件循环(event loop)
队列:先进先出 栈:后进先出 javascript的Event Loop 和 Node.js的Event Loop 区别: js(运行在浏览器),有主线程.异步任务队列的概念: node.js使用li ...
- 初探nodejs事件循环机制event loop
nodejs的特点 nodejs 具有事件驱动和非阻塞I/O的特点. 事件驱动是指nodejs把每一个任务当成事件来处理. 非阻塞I/O是指nodejs遇到I/O任务时,会从线程池调度单独的线程处理I ...
- js事件循环(event loop)
我们都知道,js是单线程的,虽然现在有 worker 的存在,但是也只是可以进行运算,并不能操作 dom: js最一开始执行的线程,是主线程,然后主线程执行完毕后,是微队列 microtask 的循环 ...
- 关于事件循环机制event loop
setTimeout(()=> { console.log('settimeout') },100) console.log('开始') console.log('结束') new Promis ...
- 深入理解JavaScript的事件循环(Event Loop)
一.什么是事件循环 JS的代码执行是基于一种事件循环的机制,之所以称作事件循环,MDN给出的解释为 因为它经常被用于类似如下的方式来实现 while (queue.waitForMessage()) ...
- js事件循环机制辨析
对于新接触js语言的人来说,最令人困惑的大概就是事件循环机制了.最开始这也困惑了我好久,花了我几个月时间通过书本,打代码,查阅资料不停地渐进地理解他.接下来我想要和大家分享一下,虽然可能有些许错误的 ...
随机推荐
- C++ STL中允许重复key的multimap
在实际的项目中可能会碰到key重复的情况,正常的MAP类型是不允许重复的key,所以就要使用multimap了,multimap的使用和map基本类似,可以无缝对接 #include <map& ...
- 为什么要用 SpringMVC 的 SessionStatus
我们可以在需要访问 Session 属性的 controller 上加上 @SessionAttributes,然后在 action 需要的 User 参数上加上 @ModelAttribute,并保 ...
- codeforces C. Diverse Permutation
C. Diverse Permutation time limit per test 1 second memory limit per test 256 megabytes input standa ...
- 转发:【PHP】转义和过滤html单、双引号及HTML标签
一.单引号和双引号转义在PHP的数据存储过程中用得比较多,即往数据库里面存储数据时候需要注意转义单.双引号: 先说几个PHP函数: 1.addslashes — 使用反斜线引用(转义)字符串: 返回字 ...
- 使用jq Deferred防止代码被回调函数分解分解的支离破碎
//移动人物 function moveInterval(stopPosotion){ var dtd = $.Deferred(); // 生成Deferred对象 var yidong= wind ...
- Android_JarZip压缩和解压文件
本文资料来自<android开发权威指南> AndroidSDK中提供了java.util.jar和java.util.zip包中的若干类和接口来完成. 压缩文件基本步骤: 1.创 ...
- hdu2647(拓扑排序)
链接:点击打开链接 题意:每一个人的基本工资为888,给出两个人的关系a,b,代表a的工资比b高问满足全部条件的话,最少须要支付多少钱 代码: #include <map> #includ ...
- sklearn 中模型保存的两种方法
一. sklearn中提供了高效的模型持久化模块joblib,将模型保存至硬盘. from sklearn.externals import joblib #lr是一个LogisticRegressi ...
- ss - float浮动模块的高度问题 解决方案
当一个Div中的子元素都是浮动元素时,该div是没有高度的.通常会带来很多困扰,解决方案如下: 低版本统配兼容: overflow: hidden; 下面是不支持低配浏览器,而且似乎该效果对 P 标签 ...
- atom搭建markdown环境及问题
1. 搭建markdown环境 > 禁用atom自带的markdown-preview插件(功能简单) > 安装插件:markdown-preview-plus@2.4.16(在markd ...