事件循环机制及常见面试题
借鉴:
《Javascript 忍者秘籍》第二版,事件循环篇
面试 | JS 事件循环 event loop 经典面试题含答案 - 知乎 (zhihu.com)
概念
- 主栈队列就是一个宏任务,每一个宏任务执行完就会执行宏任务中的微任务,直到微任务全部都执行完,才开始执行下一个宏任务。
- JS 中任务的执行顺序优先级是:主栈全局任务(宏任务) > 宏任务中的微任务 > 下一个宏任务。,所以
promise(微任务).then()的执行顺序优先级高于setTimeout定时器。 - 不能满目的将
.then的回调放入微任务队列;因为没有调用resolve或者reject之前是不算异步任务完成的, 所以不能将回调随意的放入微任务事件队列 await是一个让出线程的标志。await后面的表达式会先执行一遍,将await后面的代码加入到micro task中这个微任务是promise队列中微任务,然后就会跳出整个async函数来继续执行后面的代码。process.nextTick是一个独立于eventLoop的任务队列,主栈中的宏任务每一次结束后都是先执行process.nextTick队列,在执行微任务promise的.then()。- 每一个宏任务和宏任务的微任务执行完后都会对页面 UI 进行渲染
- 宏任务 macrotask
- script 整体代码
- setTimeout
- setInterval
- setImmediate
- I/O
- ui render
- 微任务 microtask
- process.nextTick
- promise.then
- await 后面的代码
- MutationObserver(h5新特性)
为什么 await 后面的代码会进入到promise队列中的微任务?
async/await 只是操作 promise 的语法糖,最后的本质还是promise
async function async1() {console.log('async1 start');await async2();console.log('async1 end');
}
// 上面的代码等价于 ==>
async function async1() {console.log('async1 start');Promise.resolve(async2()).then(() => {console.log('async1 end')})
}
面试题
面试题1
async function async1() {console.log('1') // 2async2().then(() => {console.log('2')})
}
async function async2() {console.log('3') // 3
}
console.log('4') // 1
setTimeout(function () {console.log('5')
}, 0)
async1();
new Promise(function (resolve) {console.log('6') // 4resolve();
}).then(function () {console.log('7')
})
console.log('8') // 5
//4 1 3 6 8 2 7 5
面试题2
setTimeout(() => {console.log(1);}, 0);async function main1() {new Promise((resolve, reject) => {console.log(2);resolve();}).then(() => {console.log(3);})await main2();console.log(7);}function main2() {console.log(8);}main1();setTimeout(() => {console.log(10);}, 0);//
2
8
3
7
1
10
面试题3
Promise.resolve().then(() => {console.log(0);return Promise.resolve('4x');}).then((res) => { console.log(res) })
Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }, () => { console.log(2.1) }).then(() => { console.log(3); }).then(() => { console.log(5); }).then(() => { console.log(6); })// 0 1 2 3 4x 5 6
面试题4 详解:(1 封私信) 关于promise输出顺序的疑问? - 知乎 (zhihu.com)
new Promise((resolve,reject) => {console.log('外部promise')resolve()
})
.then(() => {console.log('外部第一个then')new Promise((resolve,reject) => {console.log('内部promise')resolve()}).then(() => {console.log('内部第一个then')return Promise.resolve()}).then(() => {console.log('内部第二个then')})
})
.then(() => {console.log('外部第二个then')
})
.then(() => {console.log('外部第三个then')
})
.then(() => {console.log('外部第四个then')
}) //
外部promise外部第一个then内部promise
内部第一个then
外部第二个then
外部第三个then外部第四个then内部第二个then
面试题5
// A 任务
setTimeout(() => {console.log(1)
}, 20)// B 任务
setTimeout(() => {console.log(2)
}, 0)// C 任务
setTimeout(() => {console.log(3)
}, 10)// D
setTimeout(() => {console.log(5)
}, 10)console.log(4)
/* 输出
* 4 -> 2-> 3 -> 5 -> 1
*/
面试题6
setTimeout(function () {console.log(1)
}, 0);new Promise(function (resolve, reject) {console.log(2)for (var i = 0; i < 10000; i++) {if (i === 10) {console.log(10)}i == 9999 && resolve();}console.log(3)
}).then(function () {console.log(4)
})
console.log(5);
// 2, 10, 3, 5, 4, 1
面试题7
console.log("start");
setTimeout(() => {console.log("children2")Promise.resolve().then(() =>{console.log("children3")})
}, 0)new Promise(function(resolve, reject){console.log("children4")setTimeout(function(){console.log("children5")resolve("children6")}, 0)
}).then(res =>{ // flagconsole.log("children7")setTimeout(() =>{console.log(res)}, 0)
})
// start children4 children2 children3 children5 children7 children6
面试题8
这道题的难点在于是 promise2还是 async1 end 先输出。从全局宏任务之上而下执行时 await async2() 后面的代码 console.log('async1 end') 先进入 promise 中的微任务队列,最后.then() 中的console.log('promise2') 再进入到 promise 中的微任务队列。所以再开始下一轮宏任务循环之前先输出了 async1 end 再输出了 promise2。全局中的微任务执行完成开始下一轮宏任务setTimeout 最后输出 setTimeout。
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')
}, 0)
async1()
new Promise((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
面试题9
首先开始全局下的宏任务依次输出 script start, async1 start, promise1, promise3, script end。其中 await async2();,async2() 中.then()的代码先进入到promise的微任务队列,await async2(); 后面的代码再进入到promise的任务队列,console.log('promise4'); 最后进入到 promise 的任务队列。全局下的宏任务结束,开始全局下的微任务,promise 的微任务队列中按照队列的先进先出原则依次输出,promise2,async1 end,promise4。全局微任务结束,开始下一轮的宏任务setTimeout,最终输出 setTimeout。
async function async1() {console.log('async1 start');await async2();console.log('async1 end');
}
async function async2() {new Promise(function (resolve) {console.log('promise1');resolve();}).then(function () {console.log('promise2');});
}
console.log('script start');
setTimeout(function () {console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {console.log('promise3');resolve();
}).then(function () {console.log('promise4');
});
console.log('script end');
//script start,
// async1 start,
// promise1,
// promise3,
// script end,
// promise2,
// async1 end,
// promise4,
// setTimeout
面试题10
async function async1() {console.log('async1 start');await async2();setTimeout(function() {console.log('setTimeout1') // 这一部分代码会放入到 promise 的微任务队列中。},0)
}
async function async2() {setTimeout(function() {console.log('setTimeout2')},0)
}
console.log('script start');
setTimeout(function() {console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {console.log('promise1');resolve();
}).then(function() {console.log('promise2');
});
console.log('script end');
// script start, async1 start, promise1, script end,
// promise2, setTimeout3, setTimeout2, setTimeout1
相关文章:
事件循环机制及常见面试题
借鉴: 《Javascript 忍者秘籍》第二版,事件循环篇 面试 | JS 事件循环 event loop 经典面试题含答案 - 知乎 (zhihu.com) 概念 主栈队列就是一个宏任务,每一个宏任务执行完就会执行宏任务中的微任务,直到微任务全部都执行完&a…...
智能监控平台/视频共享融合系统EasyCVR接入RTSP协议视频流无法播放原因是什么?
视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。AI智能/大数据视频分析EasyCVR平台已经广泛应用在工地、工厂、园区、楼…...
c# statusStrip 显示电脑主机名、IP地址、MAC地址
控件: ToolStripStatusLabel 主机名: Dns.GetHostName() IP地址: Dns.GetHostAddresses(Dns.GetHostName())[0].ToString() 当前程序的版本: Assembly.GetExecutingAssembly().GetName().Version.ToString() 获取系统版本 …...
Cesium.CustomShader颜色值显示错误
官方示例: Cesium Sandcastle 测试过程: 1、修改示例,把customshader中的fragmentShaderText替换为如下代码 void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {//注意:下述颜色的b值是0.1&#x…...
XSLVGL2.0 User Manual 页面管理器(v2.0)
XSLVGL2.0 开发手册 XSLVGL2.0 User Manual 页面管理器 1、概述2、特性3、APIs3.1、xs_page_init3.2、xs_page_wait_inited3.3、xs_page_exit3.4、xs_page_acquire3.5、xs_page_release3.6、xs_page_set_bootlogo3.7、xs_page_setup_clear_finish3.8、xs_page_setup_is_finish…...
论文学习-Attention Is All You Need
Attention Is All You Need 目前暂时不会用到,大概了解一下即可。 Recurrent model 序列化的计算方式,难以并行,随着序列的增长,以前的记忆会逐渐丢失。而Attention机制可以观察到句子中所有的信息,不受距离影响&…...
Springboot 使用 RabbitMq 延迟插件 实现订单到期未支付取消订单、设置提醒消息
示例业务场景: 场景1:客户下单后,15分钟内未支付取消订单! 场景2:客户下单支付成功后,5分钟内商家未处理订单,需要推送一条消息提醒商家。如依旧未处理,则需要每隔2分钟消息提醒一下…...
Linux安装Tesseract-OCR(操作系统CentOS)
Linux安装Tesseract-OCR 第一步,安装依赖第二步,下载安装包第三步,安装leptonica库第四步,安装tesseract第五步,添加语言包第六步,测试 第一步,安装依赖 sudo yum install libpng-devel rpm -q…...
pair和typedef
文章目录 一、pair用法1.2、pair的创建和初始化1.3、pair对象的操作1.4、(make_pair)生成新的pair对象1.5、通过tie获取pair元素值 2、typedef2.1、什么是typedef2.2、typedef用法2.2.1、对于数据类型使用例如:2.2.2、对于指针的使用例如2.2.3、对于结构体的使用 2.…...
rdf-file:分布式环境下的文件处理
一:简介 数据量大了以后,单机解析或者生成文件的效率就很低,需要通过集群处理: 机构过来的文件:我们先对文件进行分片,在利用集群集群处理分片文件。给机构文件:分库分表数据,每个…...
Maven下载与安装教程
一、下载 Maven 进入 Maven 官网:maven.apache.org/download.cgi 选择 .zip 文件下载,最新版本是 3.9.5 二、安装 Maven 将 .zip 文件解压到没有中文没有空格的路径下。例如下图,在创建一个repository的空文件夹在他的下面,用于…...
C++(20):通过starts_with/ends_with检查字符串
C20提供了starts_with用于检查字符串是否以某个字符串开始,ends_with用于检查是否以某个字符串结束: #include <iostream> #include <string> using namespace std;int main() {string str "hello and 88";cout<<str.star…...
YOLOv8+Nanodet强强联合改进标签分配:使用NanoDet动态标签分配策略,同时集成VFL全新损失,来打造新颖YOLOv8检测器
💡本篇内容:YOLOv8+Nanodet强强联合改进标签分配:使用NanoDet动态标签分配策略,同时集成VFL全新损失,来打造新颖YOLOv8检测器 💡🚀🚀🚀本博客 YOLO系列 + 改进NanoDet模型的动态标签分配策略源代码改进 💡一篇博客集成多种创新点改进:VFL损失函数 + Nanodet…...
base64字符串转成file
分割base64字符串,获取base64的格式和ASCII字符串;使用atob()方法将base64中的ASCII字符串解码成二进制数据"字符串";将二进制数据按位放入8 位无符号整型数组中适用new File()方法将ArrayBuffer转换成file对象 const base64 &qu…...
NextJS开发:Prisma开启SQL日志输出
在 Prisma 中打印执行的 SQL 可以通过在 PrismaClient 实例上设置 log 配置参数来实现。具体步骤如下: 在你的Prisma项目根目录中,找到 prisma/schema.prisma 文件在 datasource 块中,找到你正在使用的数据库配置,并添加 provide…...
barcode.js+elementUi——实现二维码的展示——基础积累
barcode.js——实现二维码的展示——基础积累 CSDN服务器一直报错条形码需求分析1.barcode.js的引入2.html页面上的写法——我这边是一个elementUI的弹窗条形码3.script中的部分 CSDN服务器一直报错 最近不知道怎么了,CSDN一直报服务器错误,不能只有我自…...
vue2 el-table 封装
vue2 el-table 封装 在 custom 文件夹下面创建 tableList.vue直接上代码(代码比较多,复制可直接用) <template><div class"mp-list"><el-tableref"multipleTable"class"mp-custom-table":dat…...
harmonyos应用开发者高级认证考试部分答案(2)
一、判断 只要使用端云一体化的云端资源就需要支付费用(错) 所有使用Component修饰的自定义组件都支持onPageShow,onBackPress和onPageHide生命周期函数。(错) HarmonyOS应用可以兼容OpenHarmony生态(对&am…...
【物联网与大数据应用】Hadoop数据处理
Hadoop是目前最成熟的大数据处理技术。Hadoop利用分而治之的思想为大数据提供了一整套解决方案,如分布式文件系统HDFS、分布式计算框架MapReduce、NoSQL数据库HBase、数据仓库工具Hive等。 Hadoop的两个核心解决了数据存储问题(HDFS分布式文件系统&#…...
Kotlin学习——kt里的集合List,Set,Map List集合的各种方法之Int篇
Kotlin 是一门现代但已成熟的编程语言,旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作,并提供了多种方式在多个平台间复用代码,以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
IP如何挑?2025年海外专线IP如何购买?
你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
