js异步、事件循环(EventLoop)小结
单线程
众所周知,JS是单线程的语言,之所以是单线程,用一句烂大街的话就是,如果两个线程同时操作一个DOM节点,那么该以哪个为准呢,虽然多线程也有办法解决,但是js毕竟是浏览器脚本语言,不需要那么复杂
但是单线程遇到多个任务,需要排队执行,如果遇到定时器任务或者ajax请求等等,那会严重影响用户体验,于是将异步任务暂时挂起,先运行后面的任务,等异步操作返回了结果,再来执行
所以把任务分为两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous),同步任务是指在主线程上排队的任务,只有前一个任务执行完毕,才会执行后面的任务,异步任务是指不进入主线程,而是进入任务队列(task queue),当任务队列通知主线程某一个异步任务可以执行的时候,才会进入主线程执行。
同步 异步执行机制
2 主线程之外,还有一个任务队列(task queue)
3 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,里面的异步任务就会结束等待状态,进入执行栈,开始执行
4 主线程会不断的重复上面的三部内容
进程
程序运行的实例,同一个程序可以产生多个进程,一个进程可以包含多个线程
线程
操作系统能够进行运算调度的最小单位,一个只能执行一个任务,有自己的调用栈,寄存器环境,同一个进程的线程共享进程资源
浏览器进程:Browser进程,渲染进程(浏览器内核),GPU进程,网络进程,插件进程
渲染进程(浏览器内核)
GUI线程
负责渲染页面,解析html,css,构建DOM树和渲染树,当界面需要重绘(repaint)或者由于某种操作引发回流(reflow)时,该线程就会执行
JS引擎线程
解析JS,和GUI互斥,因为JS也可以操作DOM,如果两个线程同时操作DOM,可能会出现不可预期的结果,所以JS引擎运行期间,GUI处于挂起状态,GUI更新会保存在一个队列中,等JS引擎空闲时,立即执行
定时器线程
定时任务是通过定时器线程运行,他会在定时任务完成之后,通知事件触发线程,往任务队列里添加事件
异步HTTP请求线程
用来处理AJAX请求,当请求完成时,如果有回调函数,就会通知事件触发线程处理
事件触发线程
将满足触发条件的事件,添加到任务队列的末尾
EventLoop
主线程从任务队列中读取事件,这个过程是不断循环的,称为EventLoop(事件循环)
下图可以更好的帮助理解eventLoop,图中的宏任务和微任务下面会说明

微任务 宏任务
微任务(microtasks)
Promise Object.observe(监听对象变化) mutationObserve(一个类,监听DOM结构变化) postMessage(window对象之间用来通信)
宏任务(macrotasks)
script setTimeout setInterval setImmediate I/O UI rendering
异步任务分为宏任务和微任务,首先会执行script宏任务,然后执行完所有微任务之后才会执行宏任务
代码示例
需要注意的是,new Promise()里面的代码是一个参数,是同步执行的,then后面的代码才是异步执行
console.log("start");
setTimeout(() => {
console.log("setTimeout1");
});
new Promise((resolve) => {
console.log("Promise1");
resolve();
}).then(() => {
console.log("then1");
new Promise((resolve) => {
resolve();
}).then(() => {
console.log("then2");
});
setTimeout(() => {
console.log("setTimeout2");
});
});
//结果start Promise1 then1 then2 setTimeout1 setTimeout2
async function async1() {
console.log("asyncStart1");
await async2();
console.log("asyncEnd1");
}
async function async2() {
return Promise.resolve().then((res) => {
console.log("asyncPromise2");
});
}
console.log("start");
setTimeout(() => {
console.log("setTimeout");
}, 0);
async1();
new Promise((resolve) => {
console.log("promise1");
resolve();
}).then(() => {
console.log("promise2");
});
// 结果 start asyncStart1 promise1 asyncPromise2 promise2 asyncEnd1 setTimeout
js异步、事件循环(EventLoop)小结的更多相关文章
- 深入理解javascript中的事件循环event-loop
前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...
- JS JavaScript事件循环机制
区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...
- Node.js:事件循环
ylbtech-Node.js:事件循环 1.返回顶部 1. Node.js 事件循环 Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node.js 的每一个 ...
- Node.js 的事件循环机制
目录 微任务 事件循环机制 setImmediate.setTimeout/setInterval 和 process.nextTick 执行时机对比 实例分析 参考 1.微任务 在谈论Node的事件 ...
- 浏览器中 JS 的事件循环机制
目录 事件循环机制 宏任务与微任务 实例分析 参考 1.事件循环机制 浏览器执行JS代码大致可以分为三个步骤,而这三个步骤的往复构成了JS的事件循环机制(如图). 第一步:主线程(JS引擎线程)中执行 ...
- js的事件循环绑定和jQuery的隐式迭代
js的事件循环绑定和jQuery的隐式迭代 js事件循环绑定 jQuery隐式迭代 先举一个例子:给定一个ul,点击列表内的每一个li元素,使它的背景色变红,下边分别用js代码和jQuery实现. & ...
- js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)
javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...
- [浏览器事件循环] javaScript事件循环 EventLoop
前言 Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理. 先熟悉基本概念 [堆Heap] 堆是一种数据结构 ...
- JavaScript之JS单线程|事件循环|事件队列|执行栈
本博文基于知乎"JavaScript作用域问题?"一问,而引起了对JavaScript事件循环和单线程等概念与实践上的研究.深入理解. 一.概念 0.关键词:JavaScript单 ...
- 前端中的事件循环eventloop机制
我们知道 js 是单线程执行的,那么异步的代码 js 是怎么处理的呢?例如下面的代码是如何进行输出的: console.log(1); setTimeout(function() { console. ...
随机推荐
- 【探索之路】机器人篇(3)-给mwRobot建立模型
在创建一个mwRobot_description程序包那一节中,我们添加了依赖roscpp rospy std_msgs 和 urdf , 现在我们再添加一个xacro依赖. 如何添加依赖? 打开程 ...
- Class的一些使用技巧?
1.forName和newInstance结合起来使用,可以根据存储在字符串中的类名创建对象.例如 Object obj = Class.forName(s).newInstance(); 2.虚拟机 ...
- 7.24,《C Primer Plus》复习第十五章第二小题
编写一个程序,通过命令行参数读取两个二进制字符串,对这两个二进制数使用~运算符,&运算符.|运算符,并以二进制字符串形式打印结果(如果无法使用命令行环境,可以通过交互式让程序读取字符串) 编写 ...
- centos 8.x系统配置chrony时间同步服务
redhat/centos 7.x默认使用的时间同步服务为ntp服务,但是从redhat/centos 8开始在官方的仓库中移除了ntp软件,换成默认的chrony进行时间同步的服务,虽然也可以通过添 ...
- idea生成UML
原文链接http://zhhll.icu/2020/12/18/idea/%E7%94%9F%E6%88%90UML/ 使用idea直接生成UML类图 然后点击所要生成的类即可生成 由于本身的博客百度 ...
- Shiro配置Session检测时Quartz版本冲突
项目背景: shiro 1.3 + quartz 2.x 2018-9-11 22:20:35补充: 经过测试,本人发现 ,通过实现 org.apache.shiro.session.mgt.Exec ...
- 安装SVN和汉化包及基本使用
官网下载程序 和 下载汉化包. https://tortoisesvn.net/ 注意SVN汉化包版本需要和SVN版本一致,否则是无效的. 一.下载 1.进入官网,点击downloads 2.点击 ...
- kubernets与API服务器进行交互
一 为何需要与kubernets集群的API服务器进行交互 1.1 kubernets提供了一种downapi的资源可以将pod的元数据渲染成环境变量或者downward卷的形式挂载到容器的文件系 ...
- ctfshow—web—web4
打开靶机 发现与web3很相似,测试文件包含未成功 此题有两种解决方法 一.日志注入 查看日志的默认目录,得到了日志文件 ?url=/var/log/nginx/access.log 进行日志注入 & ...
- Spring Boot Scheduled定时任务特性
SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...