单线程

众所周知,JS是单线程的语言,之所以是单线程,用一句烂大街的话就是,如果两个线程同时操作一个DOM节点,那么该以哪个为准呢,虽然多线程也有办法解决,但是js毕竟是浏览器脚本语言,不需要那么复杂

但是单线程遇到多个任务,需要排队执行,如果遇到定时器任务或者ajax请求等等,那会严重影响用户体验,于是将异步任务暂时挂起,先运行后面的任务,等异步操作返回了结果,再来执行

所以把任务分为两种,一种是同步任务(synchronous),另一种是异步任务(asynchronous),同步任务是指在主线程上排队的任务,只有前一个任务执行完毕,才会执行后面的任务,异步任务是指不进入主线程,而是进入任务队列(task queue),当任务队列通知主线程某一个异步任务可以执行的时候,才会进入主线程执行。

同步 异步执行机制

1 所有的同步任务都在主线程上执行,形成一个技术栈(execution context stack)

2 主线程之外,还有一个任务队列(task queue)

3 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,里面的异步任务就会结束等待状态,进入执行栈,开始执行

4 主线程会不断的重复上面的三部内容
那么js是如何处理异步呢:通过渲染进程(浏览器内核)多线程实现异步?

进程

程序运行的实例,同一个程序可以产生多个进程,一个进程可以包含多个线程

线程

操作系统能够进行运算调度的最小单位,一个只能执行一个任务,有自己的调用栈,寄存器环境,同一个进程的线程共享进程资源

浏览器进程: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)小结的更多相关文章

  1. 深入理解javascript中的事件循环event-loop

    前面的话 本文将详细介绍javascript中的事件循环event-loop 线程 javascript是单线程的语言,也就是说,同一个时间只能做一件事.而这个单线程的特性,与它的用途有关,作为浏览器 ...

  2. JS JavaScript事件循环机制

    区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...

  3. Node.js:事件循环

    ylbtech-Node.js:事件循环 1.返回顶部 1. Node.js 事件循环 Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node.js 的每一个 ...

  4. Node.js 的事件循环机制

    目录 微任务 事件循环机制 setImmediate.setTimeout/setInterval 和 process.nextTick 执行时机对比 实例分析 参考 1.微任务 在谈论Node的事件 ...

  5. 浏览器中 JS 的事件循环机制

    目录 事件循环机制 宏任务与微任务 实例分析 参考 1.事件循环机制 浏览器执行JS代码大致可以分为三个步骤,而这三个步骤的往复构成了JS的事件循环机制(如图). 第一步:主线程(JS引擎线程)中执行 ...

  6. js的事件循环绑定和jQuery的隐式迭代

    js的事件循环绑定和jQuery的隐式迭代 js事件循环绑定 jQuery隐式迭代 先举一个例子:给定一个ul,点击列表内的每一个li元素,使它的背景色变红,下边分别用js代码和jQuery实现. & ...

  7. js的事件循环机制:同步与异步任务(setTimeout,setInterval)宏任务,微任务(Promise,process.nextTick)

    javascript是单线程,一切javascript版的"多线程"都是用单线程模拟出来的,通过事件循环(event loop)实现的异步. javascript事件循环 事件循环 ...

  8. [浏览器事件循环] javaScript事件循环 EventLoop

    前言 Event Loop即事件循环,是指浏览器或Node的一种解决javaScript单线程运行时不会阻塞的一种机制,也就是我们经常使用异步的原理. 先熟悉基本概念 [堆Heap] 堆是一种数据结构 ...

  9. JavaScript之JS单线程|事件循环|事件队列|执行栈

    本博文基于知乎"JavaScript作用域问题?"一问,而引起了对JavaScript事件循环和单线程等概念与实践上的研究.深入理解. 一.概念 0.关键词:JavaScript单 ...

  10. 前端中的事件循环eventloop机制

    我们知道 js 是单线程执行的,那么异步的代码 js 是怎么处理的呢?例如下面的代码是如何进行输出的: console.log(1); setTimeout(function() { console. ...

随机推荐

  1. C语言测一个浮点数的位数长度

    测浮点数的位数牵扯到一个精度的问题,用普通的测整形数值的方法不能实现,于是我自己写了一个测浮点数的函数. #include <stdio.h> //for printf int lengt ...

  2. 粉丝投稿!从2月份的面试被拒到如今的阿里P7,说一说自己学java以来的经验!

    个人近期面试情况 今年二月以来,我的面试除了一个用友的,基本其他都被毙了,可以说是非常残酷的.其中有很多自己觉得还面的不错的岗位,比如百度.跟谁学.好未来等公司.说实话,打击比较大. 情况基本上是从三 ...

  3. 循序渐进VUE+Element 前端应用开发(33)--- 邮件参数配置和模板邮件发送处理

    在系统处理中,有时候需要发送邮件通知用户,如新增用户的邮件确认,密码找回,以及常规订阅消息.通知等内容处理,都可以通过邮件的方式进行处理.本篇随笔介绍结合VUE+Element 前端,实现系统的邮件参 ...

  4. JavaScript基础知识梳理

    一.简单数据类型 Number.String.Boolean.Undefined.Null 1.Number: 方法: toPrecision( ) 返回指定长度的数字(范围是1到100) toFix ...

  5. linux串口通信 接收信息不完整 读取不全

    类似这种 ready.o是我用来读取串口信息的一个程序 执行结果如下: [root@localhost testPlc]# ./ready.o 0 02 1 30 2 30 3 46 4 46 5 3 ...

  6. MyBatis中id回填的两种方式

    在一种场景下需要刚刚插入数据的ID,如果数据少可以先看数据库,记下ID,但数据很多,假设一万个用户并发,每个用户都插入自己的ID,就很难记下来. 下面给定一个场景: 1 User user = new ...

  7. 关于.NET中的控制反转(三)- 依赖注入之 Autofac

    一.Autofac简介 Autofac和其他容器的不同之处是它和C#语言的结合非常紧密,在使用过程中对你的应用的侵入性几乎为零,更容易与第三方的组件集成.Autofac的主要特性如下: 组件侵入性为零 ...

  8. phpstorm2020.1最新版永久破解

    phpstorm最新安装包以及破解包下载 链接:https://pan.baidu.com/s/177DyhBWP7Lek2IAd-CVJbg 提取码:rhpz 下载安装以及先选择试用什么的傻瓜式操作 ...

  9. LeetCode 二分查找模板 III

    模板 #3: int binarySearch(vector<int>& nums, int target){ if (nums.size() == 0) return -1; i ...

  10. spring boot gateway 过滤器的执行顺序

    前言 学习官方文档,发现对于过滤器有分为三类 默认过滤器 自定义过滤 全局过滤器 于是就有一个疑问,关于这些过滤器的访问顺序是怎样的,今天就以一个demo来进行测试 准备阶段 过滤器工厂类 以此为模板 ...