IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 前端异步事件详解 -> 正文阅读

[JavaScript知识库]前端异步事件详解

前端异步事件详解

js 事件机制

javascript 的单线程

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?所以JavaScript只能是单线程

其他的辅助线程

除了单线程作为主线程之外,还存在着其他线程,例如,处理ajax请求的线程,处理点击事件的线程等等,我们不做区分,暂时管它们叫做辅助线程,也被称为js的 Event Loop

同步与异步

由上可以得出结论,主线程里面的代码就是同步执行的,辅助线程的代码就是异步执行的

主线程同步

主线程运行变量赋值、循环等操作的代码就是同步代码,特点是直接运行,不需要等待,运行的也相对快。

异步代码主要场景

  • click、mouseover等回调函数
  • ajax 请求
  • script 的refer、async 异步加载
  • setTimeout、setInterval
  • promise.then
  • 模块化异步加载场景等

执行机制

浏览器解析js代码时候,如果碰到异步,会将回调函数代码插入Event Loop 任务队列去,当执行引擎空闲时候,从任务队列里面取出来执行,遵循先入先出的原则。

setTimeout(() => {
  console.log(1)
})
setTimeout(() => {
  console.log(2)
})
// log: 1 2

碰到 promise 情况稍稍有些不一样,promise.then 会另外开辟一个任务队列,而且优先执行这个队列,这种异步情况就叫做微任务,队列就叫微任务队列,上面的setTimeout 响应的就叫 宏任务

setTimeout(() => {
  console.log(1)
})
new Promise((resolve) => {
  resolve()
}).then(() => {
  console.log(2)
})
console.log(3)
// log: 3 2 1

理解了这些,看下下面的代码

setTimeout(() => {
  console.log(1)
  new Promise((resolve) => {
    resolve()
  }).then(() => {
    console.log(2)
  })
})

new Promise((resolve) => {
  resolve()
}).then(() => {
  console.log(3)
  setTimeout(() => {
    console.log(4)
  })
})

分析: 宏任务里面有微任务,微任务里面有宏任务,首先第一个打印1的setTimeout 会入宏任务队列, 微任务一结束,打印出,3最先打印出来,然后打印4的setTimeout 会在后面入宏任务队列,然后来执行宏任务1,打印出来1,寻找当前线程的微任务2, 打印出来2,最后执行宏任务4 ,将4打印处理

//log: 3 1 2 4

接下来看以下代码

console.log('1');
setTimeout(function () {
  console.log('2');
  Promise.resolve().then(function () {
    console.log('3');
  })
  new Promise(function (resolve) {
    console.log('4');
    resolve();
  }).then(function () {
    console.log('5')
  })
})
Promise.resolve().then(function () {
  console.log('6');
})
new Promise(function (resolve) {
  console.log('7');
  resolve();
}).then(function () {
  console.log('8')
})
setTimeout(function () {
  console.log('9');
  Promise.resolve().then(function () {
    console.log('10');
  })
  new Promise(function (resolve) {
    console.log('11');
    resolve();
  }).then(function () {
    console.log('12')
  })
})

最终输出:

// 1 7 6 8 2 4 3 5 9 11 10 12

流程如下:(括号内为输出)

  1. 主线程(1)
  2. 主线程(promise 直接执行传入函数)(7)
  3. 主线程的微任务队列(6,8)
  4. 宏任务队列0
  5. 宏任务队列0
  6. 宏任务队列[0]的微任务队列(3,5)
  7. 宏任务队列1
  8. 宏任务队列[1]的微任务队列(11,12)

值得注意的是: 宏任务队列可以有多个,微任务队列在当前线程里只能有一个,可以看成是当前线程结束后的一个回调函数组。

宏任务和微任务

宏任务和微任务的关系

就拿医院挂号排队为例,宏任务就是取号排队的事件,微任务就是可能有个病人他看病过程需要拍x光、去验血,排在后面的一位只能等,这时候拍x光和验血就组成了这个病人(宏任务)的微任务队列。只有当上一个病人x光和验血都进行完之后,才能进行下一个病人诊断。

宏任务 macro-task

宏任务就是指的是浏览器dom对象原生的方法属性和基于此的封装带来的异步执行。

宏任务的来源:

  • xmlHttpRequest
  • addEventListener
  • setTimeout
  • setInterval
  • setImmediate(node.js)
  • I/O(上传文件,解析文件需要)
  • requestAnimationFrame(根据浏览器刷新频率更新操作)
  • 框架的render

微任务 micro-task(Job)

微任务也是先出后进的队列,不同的是它来源于JavaScript,所以导致当前线程只有一个微任务队列,类似于 dom 的 onload 的概念

微任务来源:

  • Promise
  • node 的 process.nextTick
  • Object.observe

无阻塞 I/O Event Loop 机制

图中的event loop中我们假设有A、B、C三个等待执行的命令队列,其中A和B都会在其执行的过程中触发I/O操作(图中右侧红色圆角矩形框,具体I/O操作可举例为“读取数据库数据”)。以A触发自身的I/O操作为例,常规的动态语言可能都会停住整个队列,等待I/O回馈后,才结束中断、继续运行下去。如果遇到I/O很耗时的情况,进程就会白白等待而浪费不少时间。为了解决此问题,NodeJS采用了event loop机制,将所有I/O操作都扔到线程池去处理,从而不再阻塞命令队列的进一步执行操作。因此从上图可以看到,即使A触发了自身的I/O,也不会阻塞队列的下一个命令B的执行。

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-10-18 17:18:34  更:2021-10-18 17:19:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:43:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码