JavaScript的事件循环机制浅析
前言
JavaScript是一门单线程的弱类型语言,但是我们在开发中,经常会遇到一些需要异步或者等待的处理操作。
类似ajax,亦或者ES6中新增的promise操作用于处理一些回调函数等。
概念
在JavaScript代码执行过程中,可以分为同步队列和异步队列。
同步任务类似我们常说的立即执行函数,不需要等待可以直接进行,可以直接进入到主线程中去执行,类似正常的函数调用等。
异步队列则是异步执行函数,类似ajax请求,我们在发起的过程中,会进入到一个异步队列,加载到任务当中时,需要进行等待,之后才能进行返回值的处理。
举个栗子
下面一段代码,我们可以先了解一些一些关于事件循环机制的一些基本的原理
console.log('1');
setTimeout(function() {
console.log('4');
}, 0);
Promise.resolve().then(function() {
console.log('2');
}).then(function() {
console.log('3');
});
console.log('5');
我们将代码打印到控制台当中,输出结果是:1,5,2,3,4
我们知道,在JavaScript中,类似定时器,以及ES6新增的promise是异步函数,回到我们上面所说的队列的概念当中,不难得出,1和5为同步执行队列
在执行完同步队列中的代码之后,再执行异步队列中的代码。
TIP
在解析异步队列的promise和定时器中,我们发现,定时器setTimeout是后执行于promise,这里我们引入JavaScript规范中的宏任务(Macro Task)和微任务(Micro Task)的概念
在JavaScript中,宏任务包含了:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务:Promise、MutaionObserver、process.nextTick(Node.js 环境)
再回到上面的定时器和promise的问题,这时候我们知道,JavaScript中,当有异步队列的时候,优先执行微任务,再执行宏任务
再次举个栗子
假如在异步队列当中存在异步队列时,我们需要怎么处理
console.log(1);
setTimeout(function() {
console.log(5);
}, 10);
new Promise(resolve => {
console.log(2);
resolve();
setTimeout(() => console.log(3), 10);
}).then(function() {
console.log(4);
})
console.log(6);
将代码执行到控制台中,得出的打印顺序是:1,2,6,4,5,3
不同于例子1当中的promise,打印2是优先于6执行的,由此我们可以知道,new Promise在执行过程中,在未执行resolve或者rejected前,所执行的代码均为同步队列中的代码。
再看4,5,3的执行顺序,在执行微任务promise执行回调resolve之后,对应的then立即执行
在打印结果中,定时器5优先执行于---->属于微任务promise中的宏任务定时器3,定时器5这个宏任务是在promise微任务这个队列之后就加进去,在promise执行完成then回调之后,promise中的宏任务才加入到队列当中,因此在定时器5之后执行
总结
在JavaScript中,宏任务包含了:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
微任务:Promise、MutaionObserver、process.nextTick(Node.js 环境);
在执行过程中,同步代码优先于其他任务队列中的代码,
定时器,promise这类任务,在执行过程中,会先加入队列,
在执行完同步代码之后,再根据宏任务和微任务的分类,先执行微任务队列,再执行宏任务队列。
文章个人博客地址:JavaScript的事件循环机制
JavaScript的事件循环机制浅析的更多相关文章
- 对javascript EventLoop事件循环机制不一样的理解
前置知识点: 浏览器原理,浏览器内核5种线程及协作,JS引擎单线程设计推荐阅读: 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理 [FE]浏览器渲染引擎「内核」 js异步编程,Promise ...
- 【运行机制】 JavaScript的事件循环机制总结 eventLoop
0.从个例子开始 //code-01 console.log(1) setTimeout(() => { console.log(2); }); console.log(3); 稍微有点前端经验 ...
- javascript的事件循环机制
JavaScript是一门编程语言,既然是编程语言那么就会有执行时的逻辑先后顺序,那么对于JavaScript来说这额顺序是怎样的呢? 首先我们我们需要明确一点,JavaScript是单线程语言.所谓 ...
- 深入理解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语法 知识. 本篇文章比较细致,如果已经对同步异步,单线程等概念比较熟悉的读 ...
随机推荐
- C语言中的typedef跟define的区别
今天用C语言练习时涉及到了typedef和define的使用问题,那么他们的区别是啥?这种情况下为什么要用typedef?哪种情况下为什么要用define呢? 学习C的时候的你是否考虑过这个问题呢? ...
- 一个label 混搭不同颜色,不同字体的文字.. by 徐
效果如图箭头所示,只需要一个label就可以做到不同颜色或不同字体的效果 1 UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(10, ...
- 把 Navigation Bar 下面那条线删掉的最简单的办法! — By: 昉
系统默认的 Navigation Bar 下面一直有条线,翻尽了文档却没找到能把它弄走的相关接口,处女座的简直木法忍啊有木有!!!! 研究了一下navigationBar下的子视图,原来只需要几行代码 ...
- LeetCode随缘刷题之赎金信
欢迎评论区讨论. package leetcode.day_12_04; /** * 为了不在赎金信中暴露字迹,从杂志上搜索各个需要的字母,组成单词来表达意思. * * 给你一个赎金信 (ransom ...
- linux_19
haproxy https实现 总结tomcat的核心组件以及根目录结构 tomcat实现多虚拟主机 nginx实现后端tomcat的负载均衡调度 简述memcached的工作原理
- 拔掉网线后, 原本的 TCP 连接还存在吗?
大家好,我是小林. 今天,聊一个有趣的问题:拔掉网线几秒,再插回去,原本的 TCP 连接还存在吗? 可能有的同学会说,网线都被拔掉了,那说明物理层被断开了,那在上层的传输层理应也会断开,所以原本的 T ...
- Solution -「洛谷 P5787」「模板」二分图(线段树分治)
\(\mathcal{Description}\) Link. \(n\) 个结点的图,\(m\) 条形如 \((u,v,l,r)\) 的边,表示一条连接 \(u\) 和 \(v\) 的无向 ...
- tep集成mitmproxy录制流量自动生成用例
使用 操作过程非常简单,流程如下: ①配置过滤域名 必须配置,不然会有很多无效流量造成数据冗余. ②启动代理 「示例」使用了反向代理,tep自带FastApi启动Mock服务: 「实际」使用正向代理, ...
- suse 12 脚本部署docker(二进制文件)
suse-linux:~ # cat /etc/issue Welcome to SUSE Linux Enterprise Server 12 SP3 (x86_64) - Kernel \r (\ ...
- Golang Sync.WaitGroup 使用及原理
Golang Sync.WaitGroup 使用及原理 使用 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.A ...