javascript的事件循环机制
JavaScript是一门编程语言,既然是编程语言那么就会有执行时的逻辑先后顺序,那么对于JavaScript来说这额顺序是怎样的呢?
首先我们我们需要明确一点,JavaScript是单线程语言。所谓单线程的意思就是只能按照一条逻辑线来运行,譬如你上班排队上公交车,先排先上,一个接一个。
首先我们需要清楚几个名词:
1.任务队列(task queue)
script中的每一个语句都是一个任务,譬如打印语句或者变量声明语句都是一个任务。
var monkey='熏悟空';
var pig='猪八盖';
如上面的代码就可以理解为两个任务。
而任务队列就是一个有规则的任务的集合,其规则就是先进先出。
2.同步任务与异步任务
所谓的同步任务就是当主线程运行到这里就能马上执行的任务,譬如:打印语句。
而异步任务则是需要等待一定时间后才能执行的语句,在这个过程中先运行他后面的语句,打个比方是猪扒盖去叫熏悟空打妖怪,熏悟空说“呆子,你先去,我去天上偷个蟠桃,看看七仙女后就来”。异步任务中的典型例子就是setTimeout延时任务。
console.log('熏悟空');
setTimeout(function(){
console.log('猪八盖')
},1000);
console.log('撒无尽');
当我主线程运行到异步任务setTimeout时就先注册一个回调函数,该函数是setTimeout中的内容,然后就去执行srtTimeout后面的打印语句。等到1000毫秒之后再去运行之前存储的回调函数。
具体两个相结合的运行顺序就是:
- 主线程自上而下执行代码。
- 同步任务直接执行,异步任务进入到事件注册表中并注册对应的回调函数。
- 等到异步任务的延时时间到了之后,事件注册表会将对应的回调函数添加到事件队列中。
- 主线程任务执行完毕之后,再去读取事件队列中的任务,将其进入到主线程中执行。
- 以上过程,不断循环往复。
以上不断循环的过程就是事件循环。
3.微任务与宏任务
javaScript不仅分为同步任务与异步任务,从另一个角度又分为了微任务与宏任务。
首先我们只需要记住几个特殊例子,也就是仅有的几个微任务:
1.Process.nextTick:node环境下的一个方法
2.Promise.then(.catch,.finally)注意这里是Promise的几个状态捕捉函数,而不是Promise本身
3.MutationObserver:元素节点的事件监听
除此以外的任务全都是宏任务,在同一个任务队列中先运行所有的同步任务,再执行异步任务,异步任务里面又包含了微任务与宏任务,先执行微任务,再执行宏任务。
小练:
console.log('俺是熏悟空');
setTimeout(function() {
console.log('俺是猪扒盖');
}, 0);
new Promise(function(resolve,reject){
console.log('俺是撒无尽');
resolve()
}).then(function() {
console.log('俺是白聋马');
})
console.log('俺是糖酸脏');
请问打印顺序是啥?
俺是熏悟空-->俺是撒无尽-->俺是糖酸脏-->俺是白聋马-->俺是猪扒盖。
逻辑理解:
1.主线程先执行‘俺是熏悟空’的同步打印任务
2.遇到setTimeout的异步任务,将其丢入事件注册表并注册对应回调函数,先不执行‘俺是猪扒盖’的打印任务
3.遇见Promise的函数执行‘俺是撒无尽’的同步打印任务。
4.遇见Promise.then异步任务,将其丢入事件注册表并注册对应回调函数,注意此时事件注册表已经有了一个setTimeout的回调,此时Promise.then的回调该放在setTimeout回调的前面还是后面呢,答案是前面,因为Promise.then属于微任务,优先级高于属于宏任务的setTimeout,先不执行‘俺是白聋马’的打印任务
5.执行‘俺是糖酸脏’的同步打印任务。
6.任务队列执行完毕,去事件注册表将延时时间(异步时间)已经到了的异步函数对应的回调函数添加到新的任务队列,再按照逻辑进行执行,先执行微任务Promise.then的回调函数,再执行setTimeout的回调函数
7.任务队列与事件注册表均无任务与事件,执行结束
以上需要注意的是
1.setTimeout的延时时间设置的是0,但是不会因为设置的0ms就变成了同步任务,不论设置多少都是异步任务,都是宏任务,因此执行顺序在同步任务之后,也在微任务之后。
2.为什么‘俺是撒无尽’的打印任务是同步打印呢,因此Promise的那几个状态捕捉函数才是异步任务,才是微任务,Promise本身函数里面的执行部分依旧是同步任务。
javascript的事件循环机制的更多相关文章
- 对javascript EventLoop事件循环机制不一样的理解
前置知识点: 浏览器原理,浏览器内核5种线程及协作,JS引擎单线程设计推荐阅读: 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理 [FE]浏览器渲染引擎「内核」 js异步编程,Promise ...
- JavaScript的事件循环机制浅析
前言 JavaScript是一门单线程的弱类型语言,但是我们在开发中,经常会遇到一些需要异步或者等待的处理操作. 类似ajax,亦或者ES6中新增的promise操作用于处理一些回调函数等. 概念 在 ...
- 【运行机制】 JavaScript的事件循环机制总结 eventLoop
0.从个例子开始 //code-01 console.log(1) setTimeout(() => { console.log(2); }); console.log(3); 稍微有点前端经验 ...
- 深入理解JavaScript事件循环机制
前言 众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心.可看HTML规范中的这段话: To ...
- JavaScript 运行机制:Event事件循环机制
JavaScript Event事件循环机制 JS是单线程的,浏览器只分配一个主线程给JS.一次只能执行一个任务,当前任务执行完后在可以执行下一个任务.任务多时,就会形成任务队列排队等待执行.但是非常 ...
- javascript事件循环机制 浅尝手记
引入 众所周知Javascript是一个单线程的机制,虽然可以依托多线程的浏览器实现页面如何实现页面复杂的渲染.事件响应,但仍不会改变其单线程的本质:所以对于js的事件循环机制的了解是一个前端人员的必 ...
- 深入浅出Javascript事件循环机制
一.JS单线程.异步.同步概念 众所周知,JS是单线程(如果一个线程删DOM,一个线程增DOM,浏览器傻逼了-所以只能单着了),虽然有webworker酱紫的多线程出现,但也是在主线程的控制下.web ...
- 浏览器中的JavaScript事件循环机制
浏览器的事件循环机制是HTML中定义的规范. JavaScript有一个主线程和调用栈,所有的任务都会被放到调用栈等待主线程执行. JS调用栈 是一种先进后出的数据结构.当函数被调用时,会被添加到栈中 ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 事件循环机制(event loop)
JavaScript 事件循环机制 (event loop) 本篇文章已经默认你有了基础的 ES6 和 javascript语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...
随机推荐
- HBase的安装与部署
一.部署前置环境 先部署分布式的高可用版的Hadoop,即ZooKeeper+Hadoop. https://www.cnblogs.com/live41/p/15483192.html * 部署的服 ...
- ST表 求 RMQ(区间最值)
RMQ即Range Minimum/Maximun Query,中文意思:查询一个区间的最小值/最大值 比如有这样一个数组:A{3 2 4 5 6 8 1 2 9 7},然后问你若干问题: 数组A下标 ...
- hdu 1160 FatMouse's Speed(最长不下降子序列+输出路径)
题意: FatMouse believes that the fatter a mouse is, the faster it runs. To disprove this, you want to ...
- spring security之 默认登录页源码跟踪
spring security之 默认登录页源码跟踪 2021年的最后2个月,立个flag,要把Spring Security和Spring Security OAuth2的应用及主流程源码研究透 ...
- 【.NET 与树莓派】用 MPD 制作数字音乐播放器
树莓派的日常家居玩法多多,制作一台属于自己的数字音乐播放机是其中的一种.严格上说,树莓派是没有声卡的,其板载的 3.5 mm 音频孔实际是通过 PWM 来实现音频输出的(通过算法让PWM信号变成模拟信 ...
- Linux环境下安装、配置Redis
linux下安装redis 官网下载链接:https://redis.io/download 安装 下载redis压缩包 1.选择Stable(5.0)下的Download 5.0.0 链接进行下载 ...
- ES6-字符串-模板字符串(复习+学习)
昨天学习了字符串对象和字符串的表示,就是利用utf-8等不同的编码方式,还有许多的对象方法,都是处理字符串的方法,挺方便的,今天我学习了一下字符串模板,这里记录i一下学习的笔记,当然,今天学习了部分内 ...
- 用 Python 修改微信(支付宝)运动步数,轻松 TOP1
用 Python 修改微信(支付宝)运动步数,轻松 TOP1 项目意义 如果你想在支付宝蚂蚁森林收集很多能量种树,为环境绿化出一份力量,又或者是想每天称霸微信运动排行榜装逼,却不想出门走路,那么该py ...
- NodeJs创建一个简单的服务器
步骤: 1 //模块化引入 2 let http = require ("http"); 3 4 //创建服务器 5 http.createServer(function(requ ...
- python中jsonpath模块,解析多层嵌套的json数据
1. jsonpath介绍用来解析多层嵌套的json数据;JsonPath 是一种信息抽取类库,是从JSON文档中抽取指定信息的工具,提供多种语言实现版本,包括:Javascript, Python, ...