前端面试之事件循环

什么是事件循环

首先, JavaScript是一门单线程的语言,意味着同一时间内只能做一件事,这并不意味着单线程就是阻塞,而是实现单线程非阻塞的方法就是事件循环

在JavaScript中,所欲任务都可以分为:

  • 同步任务:立即执行的任务,同步任务一直会直接进入到主线程中执行
  • 异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时任务等等
    在这里插入图片描述
    从上面可以看到,同步任务进入主线程,即主执行栈,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列中读取相应的任务,推入主线程执行。上面的过程不断重复就叫事件循环

宏任务和微任务

异步任务还可以细分为微任务和宏任务

微任务

一个需要异步执行的函数,执行时机主函数执行结束之后,当前宏任务执行之前

常见的微任务有:

  • Promise.then
  • MutationObserver(监听指定DOM的变化)
  • Process.nextTick(Node.js)

常见的宏任务有:

  • setTimeout/setInterval
  • postMessage、MessageChannel
  • UI rendering/UI事件(下轮事件循环执行之前)
  • Script(外层的同步代码)
  • setImmediate、I/O(Node.js)

宏任务更像在系统层面上执行的任务,微任务更像在代码层面执行的任务

在这里插入图片描述
按照这个顺序,它的执行机制是:

  • 执行一个宏任务,如果遇到一个微任务就将它放到微任务的事件队列中
  • 当前宏任务执行完成后,会查看微任务的事件队列,然后将里面的所有微任务依次执行完成

看一下的一个示例:

console.log(1)
setTimeout(()=>{console.log(2)
}, 0)
new Promise((resolve, reject)=>{console.log('new Promise')resolve()
}).then(()=>{console.log('then')
})
console.log(3)
/*** 遇到console.log(1) 直接打印* setTimeout 是宏任务 放到宏任务队列里面* Promise 中的代码是直接打印的 所以执行console.log('new Promise')* then 是微任务 放到微任务队列中* console.log(3) 这直接打印* 开始执行异步任务* 首先执行微任务 then 中的代码 打印then* 执行完微任务执行宏任务setTimeout中的代码 打印2 **/

打印的结果是:1 new Promise 3 then 2

async 与 await

async 是异步的意思,await可以理解为async wait,可以理解async就是用来声明一个异步方法,而await是用来等待异步方法执行

async
async 修饰的函数返回的是一个 Promise 对象,下面的两种方法是等效的

function f() {return Promise.resolve('TEST');
}// asyncF is equivalent to f!
async function asyncF() {return 'TEST';
}

await
正常情况下,await 命令后面是一个 Promise 对象,返回该对象结果,如果不是Promise对象,就直接返回对应的值

async function f(){// 等同于// return 123return await 123
}
f().then(v => console.log(v)) // 123

不管await后面跟着的是什么,await都会阻塞后面的代码

async function fn1 (){console.log(1)await fn2()console.log(2) // 阻塞
}async function fn2 (){console.log('fn2')
}console.log(3)
fn1()

上面的例子中,await 会阻塞下面的代码运行,先执行async外面的同步代码,同步代码执行完成后,再回到async函数中执行await之后的代码,也就是阻塞的代码

所以上述输出结果为:3 1 fn2 2

流程分析

通过对上面的了解,我们对JavaScript的各个场景的执行顺序有了大致的了解

请看以下的代码:

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

分析过程

/*** 1.遇到async1,async2函数定义不用执行,* 2.执行 console.log('script start') -> 输出:script start* 3.setTimeout 是宏任务 放到宏任务里面* 4.执行async1()* 5.进入执行async1 里执行 console.log('async1 start')  -> 输出:async1 start* 6.遇到await 执行 async2,然后阻塞await后面的代码* 7.进入执行async2 里执行 console.log('async2')  -> 输出:async2* 8.遇到Promise 执行 console.log('promise1') -> 输出:promise1* 9.执行console.log('script end') -> 输出:script end* 10.开始执行异步任务* 11.执行微任务await后面的代码 console.log('async1 end')  -> 输出:async1 end* 12.执行微任务then里面的代码 console.log('promise2')  -> 输出:promise2* 13.执行宏任务setTimeout里面的代码 console.log('settimeout')  -> 输出:settimeout
**/

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【RPC】前传

前传 本地程序用的go语言,想把main.go程序当中一些计算工作放到服务器上进行,而只需要把结果给我即可。由于平台上暂时不能运行Go代码,所以写的是python文件。 1、主要是使用ssh依赖进行连接,但是大概率是需要手动添加的&#xf…

带头+双向+循环链表

前言: 前面我们已经学习了单链表的结构及其功能特点,也了解了单链表在实现一些功能时出现的一些缺点,比如在删除某个节点前面一个节点时就需要再开一个变量来存放前面一个节点的信息,这样就显得不灵活,为了使链表实现功…

网络编程学习笔记

参考: 套接字通信部分 《TCP/IP 网络编程》以及《TCP/IP网络编程》学习笔记 socket 编程 1. 字节序 字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,也就是说对于单字符来说是没有字节序问题的&…

蓝桥杯国一,非ACMer选手保姆级经验分享

目录 一、前言二、蓝桥杯简介三、0基础计算机新手小白,赛前如何准备提高自己的获奖率?3.1 每两周参加一次【蓝桥算法双周赛】3.2 多练真题3.3 参加每一场官方校内模拟赛 四、结语 一、前言 hello,大家好,我是大赛哥(弟)&#xff…

1000道精心打磨的计算机考研题,408小伙伴不可错过

提示:408考研人看过来,超精选计算机考研1000题! 文章目录 前言1. 为什么是1000题?2. 有什么优势?【练学结合,助力强化】【难度适中,但不刁钻】【题目新颖,独具匠心】【考题预测&…

Minio

Minio学习 MinioMinio介绍安装window安装1.下载服务端和客户端文件[地址](https://min.io/download#/windows)2.创建minio相关目录3.启动minio服务方式一方式二4.查看minio版本5.访问minio控制台 linux安装docker安装 Minio Minio介绍 MinIO 是在 Apache License v2.0 下发布…

云课五分钟的一些想法

起源 自中学起,就积极学习和掌握互联网相关知识,到如今已经快30年了。 个人也全程经历了从信息时代的互联网(硬)到智能时代的大模型(软)。 整体信息到智能的基础设施,由硬到软,机…

安装表面应变计的方法及注意事项

安装表面应变计的方法及注意事项 表面应变计被广泛用于水利工程和混凝土结构中,用于测量埋设点的线性变形(应变)和应力,同时也可以测量温度。它们可以分为表面安装式和埋入式两种。 一、埋入式表面应变计 1、混凝土应变计的安装…

蓝桥杯每日一题2023.11.13

题目描述 蓝桥杯大赛历届真题 - C 语言 B 组 - 蓝桥云课 (lanqiao.cn) 题目分析 由于每次吹灭的蜡烛与年龄相同故我们想到使用前缀和可以让我们求出各个区间的和,我们将每个区间都枚举一遍,如果符合要求就输出区间开始的位置(答案&#xff…

C语言—i++、++i、条件运算符、goto语句、注释

i和i #include <stdio.h> int main() {int i5,j;j i;printf("i%d,j%d\n", i, j);i 5;j i;printf("i%d,j%d\n", i, j);system("pause");return 0;}i6,j6 i6,j5 请按任意键继续. . .条件运算符 goto语句 #include <stdio.h> int …

SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......

&#x1f9f8;欢迎来到dream_ready的博客&#xff0c;&#x1f4dc;相信您对这篇博客也感兴趣o (ˉ▽ˉ&#xff1b;) &#x1f4dc;SpringIOC和DI的代码实现&#xff0c;Spring如何存取对象&#xff1f;Controller、Service、Repository、Component、Configuration、Bean DI详…

若依框架下载文件

若依下载的逻辑是指定文件存储的路径&#xff0c;在ruoyi-admin模块下的application.yml中配置路径结尾必须要加/或者\结尾。 他使用的是虚拟路径映射&#xff0c;所以文件名必须是配置路径下真实的文件名。 若依采用的是流的方式&#xff0c;前端必须要用bolb的方式去接收&am…

四入进博会,优衣库围绕科技可持续演绎“服装进化论”

11月5日&#xff0c;第六届中国国际进口博览会在上海拉开帷幕。这些年来&#xff0c;进博巨大的平台效应&#xff0c;使其成为各个行业头部品牌的秀场&#xff0c;也持续为消费者、产业链带来惊喜。 今年&#xff0c;也是全球服装界科技知名品牌——优衣库的第四次进博之旅。从…

Node-RED系列教程-28修改UI默认背景图片

主要使用到如下节点: 实现过程如下: 步骤1:编写背景图片请求服务. http in节点配置: 读文件节点配置: http out节点配置: 到此,背景图片请求服务搭建完成。

vue3 自动导入composition-apiI和组件

1.api的自动导入 常规写法&#xff1a; <script setup>import { ref, reactive, onMounted, computed ,watch } from vue;import { useRouter } from "vue-router";const router useRouter();const person reactive ({name&#xff1a;张三&#xff0c;age…

Ubuntu取消sudo的输入密码

Ubuntu最近要安装软件&#xff0c;每次sudo都要输入一次密码&#xff0c;感觉很麻烦&#xff0c;于是想能不能设置为不输入密码&#xff0c;在网上找了一下解决办法。 主要参考这篇文章&#xff1a; Ubuntu取消sudo时输入密码 上面这篇文章使用的是vim&#xff0c;但是按照博…

会员题-力扣408-有效单词缩写

有效单词缩写 字符串可以用 缩写 进行表示&#xff0c;缩写 的方法是将任意数量的 不相邻 的子字符串替换为相应子串的长度。例如&#xff0c;字符串 “substitution” 可以缩写为&#xff08;不止这几种方法&#xff09;&#xff1a; “s10n” (“s ubstitutio n”) “sub4…

离散时间系统模型

离散时间系统模型 离散时间系统模型是表示数字滤波器的方案。MATLAB 科学计算环境支持若干种离散时间系统模型&#xff0c;这些模型将在以下章节中介绍&#xff1a; ​传递函数零极点增益状态空间部分分式展开式&#xff08;残差形式&#xff09;二阶节 (SOS)格型结构体卷积矩…

一个车厢号码识别算法(2005年的老程序----ccc)

一个车厢号码识别算法&#xff08;2005年的老程序----ccc&#xff09; 2023-09-18 ccc 程序的识别效果 对图中的车厢号码部分用上下两条线限定分为&#xff0c;然后进行识别。 从上面的识别效果可以看出&#xff0c;识别算法具有一定的鲁棒性&#xff0c;能够适应车厢号码的各…

【论文阅读】NeROIC:在线图像集合中对象的神经渲染

论文连接&#xff1a; NeROIC: Neural Rendering of Objects from Online Image Collections introduction 从在线图像集合中获取对象表示的新颖方法&#xff0c;从具有不同相机、照明和背景的照片中捕获任意对象的高质量几何形状和材料属性。这使得各种以对象为中心的渲染应…