事件循环的两道面试题
时间:2021-08-17
本文章向大家介绍事件循环的两道面试题,主要包括事件循环的两道面试题使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
事件循环(Event Loop)
进程和线程
JS为什么是单线程?
假设js同时有两个线程,一个线程想要在某个dom节点上增加内容,另一个线程想要删除这个节点,这时要以哪个为准呢?
JavaScript是单线程的,浏览器是多进程的,当打开一个tab页面就会开启一个新的进程,每个进程中又包含很多的线程,其中包括执行JavaScript代码的线程。
但是js的代码执行是在一个单独的线程中执行的,在同一个时刻只能做一件事情。
同步与异步
- js在执行代码时,代码首先进入执行栈,代码中可能包含一些同步任务和异步任务。
- 同步任务立即执行,执行完出栈,over。
- 异步任务也就是常见的
ajax
请求、setTimeout
等,代码调用到这些api的时候,WebAPIs来处理这些问题,执行栈继续执行。 - 异步任务有了运行结果时,(当
ajax
请求结果返回时),WebAPIs把对应的回调函数放到任务队列。 - 执行栈为空时来读取任务队列中的第一个函数,压入执行栈。
步骤5不断重复,执行栈为空时,系统就去任务队列中拿第一个函数压入栈继续执行。这个过程不断重复,这就是事件循环(Event Loop)。
微任务与宏任务
- 常见的宏任务:
script(整体代码)
、setTimeout
、setInterval
、I/O
、setImmedidate
- 常见的微任务:
process.nextTick
、MutationObserver
、Promise.then catch finally
process.nextTick
和setImmidate
是只支持Node环境的。
还有,process.nextTick
是有一个插队操作的,就是说他进入微任务队列时,会插到除了process.nextTick
其他的微任务前面。
面试题
setTimeout(function () {
console.log("set1");
new Promise(function (resolve) {
resolve();
}).then(function () {
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then4");
});
console.log("then2");
});
});
new Promise(function (resolve) {
console.log("pr1");
resolve();
}).then(function () {
console.log("then1");
});
setTimeout(function () {
console.log("set2");
});
console.log(2);
queueMicrotask(() => {
console.log("queueMicrotask1")
});
new Promise(function (resolve) {
resolve();
}).then(function () {
console.log("then3");
});
// pr1
// 2
// then1
// queuemicrotask1
// then3
// set1
// then2
// then4
// set2
async function async1 () {
console.log('async1 start') // 2
await async2();
console.log('async1 end') // 放到微任务队列1 // 6
}
async function async2 () {
console.log('async2') // 3
}
console.log('script start') // 1
setTimeout(function () {
console.log('setTimeout') // 宏任务队列1 // 8
}, 0)
async1();
new Promise (function (resolve) {
console.log('promise1') // 4
resolve();
}).then (function () {
console.log('promise2') // 微任务队列2 // 7
})
console.log('script end') //5
// script start
// async1 start
// async2
// promise1
// script end
// aysnc1 end
// promise2
// setToueout
原文地址:https://www.cnblogs.com/lijinbudaily/p/15152846.html
- perf ,比较好的一个程序性能测试工具
- Linux shell 程序设计5——shell中一些特殊符号的用法总结
- Linux shell 程序设计4——shell变量
- 基于CallContextInitializer的WCF扩展导致的严重问题
- 1228-redux学习笔记(摘录) | WEB前端零基础课
- 在fedora下使用搜狗拼音输入法
- 一个通过JSONP跨域调用WCF REST服务的例子(以jQuery为例)
- 【1120-WEB零基础课】| 单例模式,下周要讲
- 使用gerrit作为代码评审工具
- 如何重构你的时间序列预测问题
- 【聊】我个人眼里的ReactJs生态系统
- [WCF REST] Web消息主体风格(Message Body Style)
- apache配置https服务
- [WCF 4.0新特性] 默认绑定和行为配置
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 守护进程
- 【tensorflow2.0】自动微分机制
- Vue3.0 beta版学习笔记
- 【tensorflow2.0】低阶api--张量操作、计算图、自动微分
- mybatis之第一个mybatis程序(一)
- 进程间通信
- django-表单之创建表单(一)
- 原来sqlite3_get_table() 是这样抓取数据的!!!
- 【tensorflow2.0】中阶api--模型、损失函数、优化器、数据管道、特征列等
- 最短路径Dijkstra算法的简单实现
- django-表单之获取表单信息(二)
- 【tensorflow2.0】高阶api--主要为tf.keras.models提供的模型的类接口
- django-表单之模型表单(三)
- sqlite3数据库封装 - 动态链接库
- 【tensorflow2.0】张量的结构操作