当前位置: 首页 > article >正文

浏览器的事件循环机制

浏览器和Node的事件循环机制

  • 引言
  • 浏览器的事件循环机制

引言

由于JS是单线程的脚本语言,所以在同一时间只能做一件事情,当遇到多个任务时,我们不可能一直等待任务完成,这会造成巨大的资源浪费。为了协调时间,用户交互,脚本还有UI渲染和网络处理等行为,防止主线程阻塞才有了事件循环。而事件循环其实就是一种机制,它会不断的轮询任务队列,并将队列中的任务依此执行。

JavaScript的任务分为两种同步和异步:

  • 同步任务:在主线程上排队执行的任务,只有一个任务执行完毕,才能执行下一个任务,
  • 异步任务:不进入主线程,而是放在任务队列中,若有多个异步任务则需要在任务队列中排队等待。

因为JS是单线程,在执行代码的时候将所有函数压入执行栈中。同步任务会按照后进先出的原则以此执行。遇到异步任务时,将其放入任务队列中。当前执行栈里事件执行完毕后,就会从任务队列中取出对应异步任务的回调函数放入执行栈中继续执行。

为什么JS是单线程的脚本语言呢?

这是因为JS在执行过程中,主要操作为操作DOM树结构,如果JS有多个线程的话,多线程同时对一个DOM树进行操作,浏览器会发生错乱,根本无法判断这几个线程的优先级。

执行栈,任务队列,主线程的区分

  • 执行栈 所有的任务都是在主线程运行,形成了执行栈;
  • 任务队列 是用来存放异步任务的运行结果,事件循环是唯一的,但任务队列可以有很多个;
  • 主线程 主线程规定了要执行执行栈中的哪个事件。主线程会不停的从执行栈中读取事件,会执行完所有栈中的同步代码,这就是主线程循环。当主线程将执行栈中所有的同步任务执行完后,主线程将回去查看任务队列是否有任务,如果有,那些对应的异步任务会结束等待状态,进入执行栈并开始执行。
    更多关于异步操作Promise的解释,请移步另一篇博客

浏览器的事件循环机制

任务队列里边又分宏观任务、微观任务。

  • 宏任务:script全部代码、setTimeout、setInterval、setImmediate、I/O、UI渲染
  • 微任务:Promise.then、Process.nexTick(Node独有)、MutationObserver

new Promise是同步任务,Promise.resolve().then()是微任务
当执行栈清空后,会先检查任务队列中是否有宏任务,如果有就按照先进先出的原则,压入执行栈中执行。然后执行该宏任务产生的微任务,如果微任务中产生了新的微任务,并不会推迟到下一个循环中,而是在当前循环中继续执行。 当执行这一轮的微任务完毕后,开启下一轮循环,执行任务队列中的宏任务。
一次事件循环会处理一个宏任务和所有这次循环中产生的微任务。

对于宏任务和微任务的关系,那就是微任务始终跟在当前宏任务的后面,当前宏任务还没执行完之前,遇到宏任务先扔一边,遇到微任务就跟在当前宏任务后面。
在这里插入图片描述
这段代码的解释:首先JS本身就是一个宏任务,所以遇到setTimout时候会将这个宏任务先放到一边,继续往下执行,遇到了new Promise同步任务,所以输出同步宏任务Promise,继续往下执行,遇到微任务,跟在了当前宏任务(JS)后面,随后输出同步宏任务,当前宏任务(JS)执行完毕,执行跟在这个宏任务后面的微任务,输出同步微任务Promise,这个时候当前宏任务带着的微任务全部执行完毕,第一个事件循环结束,开启第二个事件循环,读取第二个宏任务,遇到了new Promise同步任务,直接输出,随后遇到了微任务,跟在了当前这个宏任务后面,继续向下执行,输出异步宏任务,当前宏任务执行完毕,开始执行跟在后面的微任务,输出异步微任务then。


http://www.kler.cn/a/421639.html

相关文章:

  • springboot利用easypoi实现简单导出Excel
  • [高等数学学习记录] 泰勒公式
  • 去哪儿Java开发面试题及参考答案
  • 渗透测试--Windows凭证收集
  • 更换 Git 项目的远程仓库地址(五种方法)
  • 腾讯云平台 - Stable Diffusion WebUI 下载模型
  • 电池SOH预测模型 | 基于VAE—BiGRU变分自编码器结合深度学习模型(Python/Matlab)
  • Python实现网站资源批量下载【可转成exe程序运行】
  • 计算机网络常见面试题总结(上)
  • KAN-Transfomer——基于新型神经网络KAN的时间序列预测
  • 基于Java Springboot校园论坛APP且微信小程序
  • Go学习笔记之数据类型转换
  • 基于OpenCV的拆分和合并图像通道实验案例分享_基于RK3568教学实验箱
  • 权限提升漏洞之Netlogon协议详解 以及可能出现得漏洞分析
  • 【035】基于51单片机俄罗斯方块游戏机【Proteus仿真+Keil程序+报告+原理图】
  • Scala模拟匹配
  • 怎么做DNS污染检测
  • 【docker】Dockerfile指令讲解,与企业案例应用
  • 数据结构自测5
  • java垃圾回收机制介绍
  • linux模拟试题
  • Seatunnel解决ftp读取json文件无法读取数组以及格式化之后的json无法解析的问题
  • TypeScript和JavaScript的区别
  • 如何使用brew安装phpredis扩展?
  • 零基础学安全--Burp Suite(4)proxy模块以及漏洞测试理论
  • CTF之WEB(php弱类型绕过)