深入理解事件循环机制
浏览器常驻的线程
- js引擎线程(解释执行js代码、用户输入、网络请求)
- GUI线程(绘制用户界面、与js主线程是互斥的)
- http网络请求线程(处理用户的get,post等请求,等返回结果后将回调函数推入任务队列)
- 定时器触发线程(setTimeout,setIntervat等待事件结束后把执行函数推入任务队列中)
- 浏览器事件处理线程(将click,mouse等交互事件发生后将这些事件放入事件队列中)
UI主线程负责协调运转
【例】当js引擎是单线程的,若当前执行的函数快没有处理完,不会执行下一个函数块,此处写一个死循环去证明该点
<body><button id="btn">run</button>
</body>
<script type="text/javascript">
var oBtn = document.getElementById('btn');
function dieLoop() {while (true) {}
}
oBtn.onclick = function () {console.log("a");
}
</script>
【结果】点击按钮打印"a",执行函数dieLoop(作死的人才去执行这个函数,反正我卡死了),再点击按钮,不执行该点击事件
JS引擎线程和GUI线程—互斥
JS可以操作DOM元素,进而会影响到GUI的渲染结果因此JS引擎线程与GU渲染线程是互斥的。也就是说当JS引擎线程处于运行状态时,GUI渲染线程将处于冻结状态。
JS执行机制
- 单线程—同一时间只能做一件事
- 使用单线程的原因:js设计出来就是为了与用户交互,处理DOM,假如js是多线程,同一时间一个线程想要修改DOM,另一个线程想要删除DOM,问题就变得复杂许多,问题就变得复杂,如果引入“锁”的机制,就回到了被其他语言尴尬的困境(什么被其他语言尴尬的困境?)
- 操作大量数据的解决办法:单线程计算能力有限,大量数据需要计算渲染的话,需要配合后端进行操作(VUE和node.js配合,即SSR技术)
- 异步执行:JAvaScript是基于单线程运行的,同时又可以异步执行,一般来说这种既是单线程又是异步的语言都是基于事件来驱动的,恰好浏览器给JavaScript提供了这样的环境
- 流程图如下
解释:
- 同步和异步任务分别进入不同的执行“场所”,同步的进入主线程,异步的进入Event Table并注册函数
- 当指定的事情完成时,Event Table会将这个函数移入Event Queue
- 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行,
- 上述过程不断重复,即Event Loop(事件循环)
同步任务
【例】
function foo(ot) {function bar(it) {debugger;console.log(it);}bar(10);console.log(ot);
}
foo(20);
【结果】
【分析】
- 代码没有执行的时候,执行栈为空;
- foo函数执行时,创建一帧,其中包含形参、局部变量(预编译过程),然后把这一帧压入栈中;
- 执行foo函数中的bar函数;
- 创建一帧,压入栈中;
- bar函数执行完毕,弹出栈;
- foo函数执行完毕,弹出栈;
- 执行栈为空。
异步任务
【例】
$.ajax({url : '',data : {},success : function (data) {console.log(data);}
});
console.log('run');
【分析】
- Aja进入Event Table,注册回调函数success;
- 执行 console.log('run');
- Ajax事件完成http网络请求线程,把任务放入任务队列Event Queue中
- 主线程读取任务执行success函数
深入理解定时器
setTimeout的等待事件结束后并不是直接执行的,而是先推入浏览器的一个任务队列,在同步队列结束后,再依次调用任务队列中的任务
setTimeout(function(){},0)实际上,就算JS主线程中的执行栈为空,也达不到0毫秒,根据HTML标准,最低4毫秒
setInterval是每隔一段时间把任务放到Event Queue之中
【例】
var firstTime = + new Date();
function loop(d) {for (var i = 0; i < d; i++) {console.log(i);}
}
loop(10000);
setTimeout(function () {var time = + new Date() - firstTime;console.log(time);
},100);
【结果】
【分析】setTimeout并不是100毫秒之后执行的,而是100毫秒后放入任务队列,在同步队列的任务执行完毕后,执行任务队列的setTimeout。
深入理解事件循环机制相关推荐
- 对JavaScript事件循环机制的理解
前言: 这次主要整理一下自己对 Js事件循环机制,同步,异步任务,宏任务,微任务的理解,大概率暂时还有些偏差或者错误.如果有,十分欢迎各位纠正我的错误! 一.事件循环和任务队列产生的原因: 首先,JS ...
- boost log 能不能循环覆盖_前端基础进阶(十四):深入核心,详解事件循环机制...
Event Loop JavaScript的学习零散而庞杂,很多时候我们学到了一些东西,但是却没办法感受到进步!甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直在试图 ...
- js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)...
javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...
- es5如何实现promise_ES5实现Promise(1) - 事件循环机制
因为公司业务面向国企以及传统企业,所以代码需要能够在ie9以上运行,所以在项目中无法用一些新技术.比如ES6的Promise,这个Promise真的是太好使了,就跟便秘时使了开塞露一般.由于Promi ...
- JS事件循环机制:同步与异步任务 之 宏任务 微任务
JS事件循环机制:同步与异步任务 之 宏任务 微任务 阅读目录 javascript事件循环 setTimeout和setInterval中的执行时间 宏任务和微任务 javascript是单线程,一 ...
- 事件循环机制 + ES7:Async/Await(基于generator原理实现)附详细示例分析
文章目录 一.事件循环 任务队列 宏任务和微任务 循环机制 简单示例 二.Async/Await 1. async 2. await 3. 原理 4. 示例(红字分析为关键) 一.事件循环 任务队列 ...
- 浏览器中的事件循环机制
浏览器中的事件循环机制 网上一搜事件循环, 很多文章标题的前面会加上 JavaScript, 但是我觉得事件循环机制跟 JavaScript 没什么关系, JavaScript 只是一门解释型语言, ...
- 浏览器事件循环机制与Vue nextTick的实现
浏览器事件循环机制 先上一段简单的代码 console.log('aa'); setTimeout(() => { console.log('bb')}, 0); Promise.resolve ...
- js结束当前循环关键词_干货||什么是事件循环机制
事件循环机制 经常有小伙伴问到我什么是 js 的事件循环机制,这里我就简单来给这些有困惑的小伙伴进行一下解答. 我将从下面几个方面来循序渐进的为大家来进行讲解: 区分进程和线程 浏览器的多进程 浏览器 ...
最新文章
- B - Networking - poj 1287
- CentOS 6.2 下samba 服务的配置
- 6、JavaScript进阶篇③——浏览器对象、Dom对象
- 《图解HTTP》读书笔记--第3章HTTP报文内的HTTP信息
- linux还原系统_怎么成为一名合格的Linux运维工程师
- 手把手教你使用Numpy、Matplotlib、Scipy等5个Python库
- 【Unity|C#】基础篇(1)——基础入门
- AndroidStudio_android多线程和异步任务_要学内容介绍_相关知识点---Android原生开发工作笔记241
- java删除数组里的两个_java – 如何从两个数组列表中删除常用值
- PS把一张白纸里的黑色图形抠出来
- php 邮件发送是html 没样式_PHP 下的 Socket 编程--发送邮件
- ArrayList源码解读(jdk1.8)
- 大数据Hadoop详细介绍(v2016)
- kux播放器android,kux格式转换工具
- FPGA自学:利用D触发器实现分频
- 开发低功耗蓝牙4.0血压计连接与收发数据
- CoreText(四):行 CTLineRef
- weinre远程调试mobile页面
- 哈希表、红黑树、B树、B+树基础
- 嵌入式软件工程师面试题(九)