JS运行机制、Event Loop

1、JS运行机制

   JS最大的特点就是单线程,所以他同一时间只能做一件事情。使单线程不阻塞,就是事件循环。

在JS当中分为两种任务:

  • 同步任务:立即执行的任务,一般放在主线程中(主执行栈)。
  • 异步任务:异步执行的任务,进入任务队列(task queue)。只有任务队列通知主线程,某个异步任务可以执行力,该任务才会进入主线程执行。

事件循环就是不断重复上面两步骤、异步与同步任务执行如下。

2、宏任务与微任务

        异步任务又分为宏任务和微任务。

常见的微任务有:

  • Promise.then
  • Async/Await
  • MutationOberver
  • Object.oberver
  • process.nextTick

常见的宏任务有:

  • script(可以理解其为外层同步代码)
  • setTimeout/setInterval
  • UI
  • postMessage\MessageChannel
  • I/O
  • setImmediate

他的运行机制是:

  1. 执行一个宏任务、如果遇到微任务就将他放到微任务的队列中
  2. 执行当前宏任务后,检查微任务事件队列,将其执行完毕
  3. 循环上面的步骤如下图

3、Async/Await

     async是异步的意思,await可以裂解为async wait。所以可以理解为:

  • async:声明一个异步的方法
  • await:等待异步方法执行

Async/Await相对于Promise的优势:

  • Promise虽然拜托了地狱回调,但是他很的链式调用也会带来阅读负担
  • Async/Await是异步函数但是几乎同步的写法,非常优雅
  • Async/Await错误处理友好,可以使用成熟的try/catch
  • 调试友好,Promise由于没有代码块,不能反回表达式的箭头函数中设置断点
  1. async ,awit命令后面返回Promise对象。如果不是对象直接返回对应的值。
function f() {
    return Promise.resolve('TEST');
}

// asyncF is equivalent to f!
async function asyncF() {
    return 'TEST';
}
  1.  不管await后面跟着是什么,await都会阻塞后面的代码
async function fn1 (){
    console.log(1)
    await fn2()
    console.log(2) // 阻塞
}

async function fn2 (){
    console.log('fn2')
}

fn1()
console.log(3)

//1,fn2,3,2

         上面例子中,await会阻塞下面的代码(即加入微任务队列),先执行async外面的同步代码,执行完毕之后回到async函数执行之前阻塞的代码。

4、流程分析

     下面一个案例可以看到时间循环机制为了达到单线程不阻塞,他的执行流程是怎么样的。

async function async1() {
    console.log('async1 start')
    await async2()
    console.log('async1 end')
}
async function async2() {
    console.log('async2')
}
console.log('script start')
setTimeout(function () {
    console.log('settimeout')
})
async1()
new Promise(function (resolve) {
    console.log('promise1')
    resolve()
}).then(function () {
    console.log('promise2')
})
console.log('script end')

//script start,async1 start,async2,promise1,script end,async1 end,promise2,settimeout

 分析:

  • 执行同步任务async1、promise、console直接打印script startasync1 startasync2promise1script end
  • 遇到await、Promise.then添加到微任务队列
  • 遇到settimeout添加到宏任务队列
  • 清空微任务队列打印async1 endpromise2
  • 处理宏任务队列打印settimeout

参考文献:
javaScript运行机制 (同步与异步)的理解_js同步与异步的机制-CSDN博客

面试官:说说你对事件循环的理解 | web前端面试 - 面试官系列

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/293255.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业级 npm 私有仓库部署方案

本文作者系360奇舞团前端开发工程师 淘宝 NPM 镜像站切换新域名时,放了一张知乎博主天猪的图片,如下: _图片来源:https://zhuanlan.zhihu.com/p/432578145 看着逐年增长的访问量,不禁让人感慨,npm 的出现&a…

并发编程大杀器,京东多线程编排工具asyncTool

一、简介 并发编程大杀器,京东多线程编排工具asyncTool,可以解决任意的多线程并行、串行、阻塞、依赖、回调的并行框架,可以任意组合各线程的执行顺序,带全链路执行结果回调。多线程编排一站式解决方案。 二、特点 多线程编排&am…

GPT/GPT4科研应用与AI绘图技术及论文高效写作(建议收藏)

详情点击链接:GPT/GPT4科研实践应用与AI绘图技术及论文高效写作 一OpenAI 1.最新大模型GPT-4 Turbo 2.最新发布的高级数据分析,AI画图,图像识别,文档API 3.GPT Store 4.从0到1创建自己的GPT应用 5. 模型Gemini以及大模型Clau…

客服系统接入FastGPT

接入FastGPT 点击【应用】【外部使用】【API访问】【新建】新建一个KEY,同时也可以看到我们的API根地址 这个根地址和Key可以填入任何支持OpenAI接口的应用里,这个接口是兼容OpenAI格式。 在客服系统【知识库AI配置】里填上接口地址和接口密钥。这样我…

图像分割实战-系列教程10:U2NET显著性检测实战2

🍁🍁🍁图像分割实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Pycharm中进行 本篇文章配套的代码资源已经上传 U2NET显著性检测实战1 U2NET显著性检测实战2 5、残差Unet模块 class RSU7(nn.Module):#UNet07DRES…

04.MySQL的基本操作

MySQL的基本操作 一、连接和断开MySQL服务器1、通过系统服务器启动、停止MySQL服务器2、通过命令提示符(DOS)启动、停止MySQL服务器2.1 启动 MySQL 服务器:2.2 停止 MySQL 服务器:2.3 登录和退出mysql 二、创建和管理数据库2.1 创…

k8s---pod基础下

k8s的pod与docker重启策略的区别 k8s的重启策略 always deployment的yaml文件只能是always,pod的yaml三种模式都可以。不论正常退出还是非正常退出都重启。OnFailure:正常退出不重启,非正常退出会重启Never:正常退出和非正常退出…

奇技淫巧:如何给项目中的RabbitMQ添加总开关

本文主要分享了如何给项目中的RabbitMQ添加总开关,通过简单配置开/关RabbitMQ。 一、需求背景 SpringBoot项目里使用了RabbitMQ,但某些场景下,不希望项目启动时自动检查RabbitMQ连接 例如: 在开发不需要RabbitMQ的功能过程中&…

Prometheus插件安装(cadvisor)

简介 当docker服务数量到一定程度,为了保证系统的文档,我们就需要对docker进行监控。一般情况下我们可以通过docker status命令来做简单的监控,但是无法交给prometheus采集,因此谷歌的cadvisor诞生了。cadvisor不仅可以轻松收集到…

【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

文章目录 一、说明二、用于创建对象的2.1、Component注解2.1.1、定义Bean2.1.2、主配置文件配置扫描注解2.1.3、测试2.1.4、Component注解总结 2.2、Controller注解2.3、Service注解2.4、Repository注解 三、用于注入数据的3.1、Autowired注解3.1.1、定义Bean3.1.2、主配置文件…

Selenium-java元素等待三种方式

第二种方式需要写在创建driver时的代码下面 第三种则是对每个定位元素进行配置

探索Commons Exec管理外部进程

第1章:引言 咱们在日常的Java开发中,经常会遇到需要调用外部进程或命令的场景。比如说,可能需要在Java程序中启动一个外部的脚本,或者执行一个系统命令。Java虽然提供了Runtime和ProcessBuilder类来处理这类需求,但说…

Docker Linux快速安装及Nginx部署

前言 最近正在部署一套新的Linux服务器环境,基于Docker来部署所有的应用,顺便整理了一套经过验证的操作手册,以便大家遇到类似需求时,可以直接拿来用。 本文会涉及以下知识点:Docker的Linux安装和卸载、Docker用户组…

【网络安全】Nessus部署自动更新和端口权限开放

文章目录 Nessus 自动更新配置Nessus服务端口开放Nessus profession 版本需要开放端口Sensor ProxyTenable Security Center (TSC)Tenable OT Security (TOT)Tenable OT Security Enterprise Manager (IEM)Tenable OT Security Industrial Core Platform (ICP)Tenable OT Secur…

基于卷积神经网络的回归分析

目录 背影 卷积神经网络CNN的原理 卷积神经网络CNN的定义 卷积神经网络CNN的神经元 卷积神经网络CNN的激活函数 卷积神经网络CNN的传递函数 卷积神经网络的回归分析 完整代码:卷积神经网络的回归分析(代码完整,数据齐全)资源-CSDN文库 https://download.csdn.net/download/…

基于深度学习大模型实现离线翻译模型私有化部署使用,通过docker打包开源翻译模型,可到内网或者无网络环境下运行使用,可以使用一千多个翻译模型语言模型进行翻译

基于深度学习大模型实现离线翻译模型私有化部署使用,通过docker打包开源翻译模型,可到内网或者无网络环境下运行使用,可以使用一千多个翻译模型语言模型进行翻译,想要什么语种直接进行指定和修改就行。 环境要求,电脑内存低于8G建议不要尝试了,有无GPU都可以运行,但是有…

秋招复习之栈与队列

前言 1 栈 「栈 stack」是一种遵循先入后出逻辑的线性数据结构。 我们可以将栈类比为桌面上的一摞盘子,如果想取出底部的盘子,则需要先将上面的盘子依次移走。我们将盘子替换为各种类型的元素(如整数、字符、对象等)&#xff0c…

释放创造力:可视化页面渲染引擎在低代码开发平台的应用

本文由葡萄城技术团队发布。转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 什么是页面渲染引擎? 页面渲染引擎是低代码开发平台的核心组件之一,它负责将开发者设计的页面布局和用户…

Docker 存储卷管理

一、存储卷简介 存储卷是一种方便、灵活、高效的Docker容器内数据存储方式。存储卷可以在容器内的不同进程间共享数据,并且可以在容器之间共享和重用。 二、存储卷的优点 可以在容器之间共享和重用,避免了在不同容器之间复制数据的繁琐。对数据卷的修…

Flume基础知识(七):Flume 事务与 Flume Agent 内部原理

1. Flume 事务详解 2. Flume Agent 内部原理 重要组件: 1)ChannelSelector ChannelSelector 的作用就是选出 Event 将要被发往哪个 Channel。其共有两种类型, 分别是 Replicating(复制)和 Multiplexing(多…