javascript --- event loop

栗子1

  • 求下面函数的输出
console.log('script start');setTimeout(() => {console.log('setTimeoout');
}, 0);Promise.resolve().then(function(){console.log('promise1');
}).then(function(){console.log('promise2');
})
console.log('script end');

在这里插入图片描述

  • 说明: 在"promise2"和"setTimeoout"之间有"<· undefined"
  • “<· undefined”: 其实是进入了下一轮事件循环
  • 可视化展示: https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

JS的执行顺序

  • 原则:
  1. 事件循环过程中,每次只执行1个宏任务
  2. 在执行宏任务之前,首先检查微任务队列是否为空.若存在微任务,则先执行微任务

常见的宏任务和微任务

  • 常见的宏任务: setTimeout、setInterval、setImmediate(Node)、requestAnimationFrame(浏览器)、I/O、UI rendering(浏览器)
  • 常见的微任务: process.nextTick(Node)、promise.then()、Obeject.observe、MutationObeserve

栗子1说明:

  • 在了解了执行顺序以及宏/微任务之后,再看上面的栗子1:
  • console.log('script start'): 同步任务, 输出 ‘script start’
  • setTimeout(function(){ console.log('setTimeout') },0): 这是一个宏任务,会将函数function(){ console.log('setTimeout') }推到宏任务队列中
  • Promise.resovle().then(function(){console.log('promise1')}).then(function(){console.log('promise2')}): 2个微任务,一次推入微任务队列
  • console.log('script end'): 同步任务,输出 ‘script end’
  • 到了这里,开始执行事件循环的下一轮,根据原则2.先检擦微任务队列是否为空,此时不为空,于是执行队列的第一个(即输出 ‘promise1’),然后出队,在检查微任务队列是否为空(此处不为空,故输出’promise2’,出队),在检查…
  • 当微任务队列为空,代表当前事件循环结束,所以会输出一个返回值,此处未设定,故输出"<· undefined"
  • 从宏任务队列中读取,输出(“setTimeout”)

栗子2

  • 求以下函数的输出结果
new Promise(resolve => {console.log("resolve")resolve()}).then(() => console.log("promise then..."))setImmediate(() => {console.log("set immediate...")
})setTimeout(() => {console.log("set Timeout ...");
}, 0);process.nextTick(() => {console.log("nextTick")
})

在这里插入图片描述

  • 说明:
  1. Promise是宏任务,其里面的函数是同步的.即会执行console.log('resolve')
  2. nextTick可以理解为在其他类型微任务的前面入队.

浏览器中的事件循环

  • 执行全局Script的同步代码
  • 执行microtask任务
  • 从宏任务队列中取出队首一个任务
  • 执行该任务
  • 任务执行完毕,检查是否有微任务(有则执行,否则执行第一步)

Node.js的Event Loop过程:

  1. 执行全局Script的同步代码
  2. 执行microtask微任务,先执行所有 Next Tick Queue中的所有任务,再执行Other Microtask Queue中的所有任务
  3. 开始执行macrotask宏任务,共6个阶段,从第1个阶段开始执行相应每一个阶段macrotask中的所有任务,六个阶段: Timers Queue -> 步骤2 -> I/O Queue -> 步骤2 -> Check Queue -> 步骤2 -> Close Callback Queue -> 步骤2 -> Timers Queue…
  • MacroTask包括: setTimeout、setInterval、setImmediate(Node)、requestAnimation(浏览器)、IO、UI rendering(浏览器)
  • MicroTask包括:s process.nextTick(Node)、Promise.then、Object.observe、MutationObserver

setTimeout 和 setImmediate

  • setImmediate():方法用于中断长时间运行的操作,并在完成其他操作后立即运行回调函数

  • 栗子:

setTimeout(() => {console.log('setTimeout');
}, 0);setImmediate(() => {console.log('setImmediate');
})

在这里插入图片描述
同样的代码执行的结果不确定:

  • setTimeout/setInterval的第二个参数取值范围是: [1, 2^31 -1],如果超过这个范围就会初始化为1,即 setTimeout(fn, 0) === setTimeout(fn, 1);
  • setTimeout的回调函数再timer阶段执行,setImmediate的回调函数再check阶段执行,event loop的开始会检查timer阶段,但是再开始之前到timer阶段会消耗一定时间,就会出现以下情况:
  1. timer前的准备时间超过1ms, 满足loop -> time >=1, 则执行timer阶段(setTimeout)的回调函数
  2. timer前的准备时间小于1ms,则先执行check阶段(setImmediate)的回调函数,下一次event loop执行timer阶段(setTimeout)的回调函数

栗子3

console.time("start");
setImmediate(function() {console.log(1);
});
setTimeout(function() {console.log(2);
}, 10);
new Promise(function(resolve) {console.log(3);resolve();console.log(4);
}).then(function() {console.log(5);console.timeEnd("start")
});
console.log(6);
process.nextTick(function() {console.log(7);
});
console.log(8);

在这里插入图片描述

  • 说明:
  1. 首先执行script代码,输出3468
  2. 执行nextTick任务,输出7
  3. 执行microtask, 输出5, start: 15.232ms
  4. 如果事件大于10ms,则执行宏任务 “输出2”, 否则输出"1"

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

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

相关文章

sublime 设置自动换行

1.打开sublime,点击preferences -> settings 2.将word_wrap的值由auto修改为true&#xff08;若没有word_wrap&#xff0c;手动添加&#xff09; 转载于:https://www.cnblogs.com/hitwgs/p/8821316.html

Java 试题三

Java 试题三 1、java类是否可以多继承&#xff0c;怎么实现多继承&#xff1f; 答&#xff1a;java没有多继承&#xff0c;但可以通过接口的形式来达到多继承的目地。 2、我比较两个String总是false&#xff0c;但是它们明明都是”abc” &#xff01; 答&#xff1a;比较Str…

Cent os常见操作命令

1.查看防火墙状态&#xff1a;firewall-cmd –-state 2.关闭防火墙&#xff1a;systemctl stop firewalld.service 3.禁止防火墙开机启动&#xff1a;systemctl disable firewalld.service 4.关闭selinux&#xff1a;vi /etc/selinux/config&#xff0c;然SELINUXdisabled 5.查…

koa --- 使用中间件多层级抛出错误

说明 能够熟练的掌握错误的抛出,可以在一定程度上提高代码的开发效率和可读性 构造错误 本栗采用调用一个不存在的函数来抛出错误 const Koa require(koa); const app new Koa();// 响应时间输出中间件 app.use(async (ctx, next) > {await next();// 获取响应头,印证…

电脑的真正价值

1.不是应用程序&#xff0c;而是开发程序 2.高级语言就像是人类的语言&#xff0c;低级语言就像是一个全心全意帮我的社交专家&#xff0c;他帮我说服电脑实现我的指令 3.高级语言就是字节码&#xff0c;低级语言帮我转换成机器码 4.有时候&#xff0c;高级语言的一个眼神&…

Java 试题四

Java 试题四 1、abstract class 和interface 有什么区别? 【基础】 答&#xff1a;声明方法的存在而不去实现它的类被叫做抽象类&#xff08;abstract class&#xff09;&#xff0c;它用于要创建一个体现某些基本行为的类&#xff0c; 并为该类声明方法&#xff0c;但不能…

PyInstaller用法

pyinstaller定义&#xff1a;PyInstaller是一个压缩python文件成为可执行程序的一个软件。 pyinstaller工作原理&#xff1a;① 它会扫描你所有的Python文档&#xff0c;并分析所有代码从而找出所有你的代码运行所需的模块。② PyInstaller会将所有这些模块和你的code放在一个文…

koa --- 监听路由,并使用模板引擎渲染显示

使用路由 /Koa实战/routes/index.js const Router require(koa-router); const router new Router();router.get(/, ctx > {ctx.body index; });module.exports router/Koa实战/routes/users.js const Router require(koa-router); const router new Router({prefi…

公共平台服务治理与鉴权

问题 解决问题 鉴权 注册 管理 总结聊一聊最近了解的公司服务治理平台&#xff0c;主要是思想&#xff0c;理念&#xff0c;而不是一种技术或框架。整个平台设计&#xff0c;融入了OAUTH2认证&#xff0c;融入了微服务思想&#xff0c;帮助公司各系统在复杂的IT架构下&#xff…

Java 试题五

Java 试题五 1、运行时异常与一般异常有何异同 答&#xff1a;异常表示程序运行过程中可能出现的非正常状态&#xff0c;运行时异常表示虚拟机的通常操作中可能遇到的异常&#xff0c;是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常&#xff0c;…

【初赛】概率与期望学习笔记

一、事件 1、单位事件、事件空间、随机事件 在一次随机试验中可能发生的不能再细分的结果被称为单位事件&#xff0c;用 $ E $ 表示。在随机试验中可能发生的所有单位事件的集合称为事件空间&#xff0c;用 $ S $ 来表示。例如在一次掷骰子的随机试验中&#xff0c;如果用获得的…

koa --- 扩展hbs方法

moment 是一款常用的处理时间的库传入 1999-03-01T16:00:00.000Z YYYY/MM/DD输出 1999/03/02 const moment require(moment);const myDatePattern (date, pattern) >{return moment(date).format(pattern) } 给扩展hbs功能. 放在 utils/helper.js 下方便管理 const hb…

go系列 锁的初识

Go基础之锁的初识 当我们的程序就一个线程的时候是不需要用到锁的&#xff0c;但是通常我们实际的代码不会是单个线程的&#xff0c;所有这个时候就需要用到锁了&#xff0c;那么关于锁的使用场景主要涉及到哪些呢&#xff1f; 当我们多个线程在读相同的数据的时候则是需要加锁…

Java 试题六

Java 试题六 1、Collection 和 Collections的区别 答&#xff1a;Collection是集合类的上级接口&#xff0c;继承与他的接口主要有Set 和List。Collections是针对集合类的一个帮助类&#xff0c;他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。 2、Set里…

node --- 实现session认证.

跨域认证的问题 互联网服务离不开用户认证.一般流程如下: 1、用户向服务器发送用户名和密码。 2、服务器验证通过后&#xff0c;在当前对话&#xff08;session&#xff09;里面保存相关数据&#xff0c;比如用户角色、登录时间等等。 3、服务器向用户返回一个 session_id&…

回信,我的好朋友王一涵

好了&#xff0c;不拖了&#xff0c;沏一杯咖啡&#xff0c;把信写完。因为再拿好吃的贿赂你&#xff0c;贿赂不起了—— 一个胖子可以吃穷我的。 王一涵凹&#xff0c;不得了不得了。微胖肉质女生&#xff0c;关于体重我就不提了&#xff0c;只有我知道嘿嘿嘿&#xff0c;在我…

编写基于Property-based的单元测试

编写基于Property-based的单元测试 作为一个开发者&#xff0c;你可能认为你的职责就是编写代码从而完成需求。我不敢苟同&#xff0c;开发者的工作是通过软件来解决现实需求&#xff0c;编写代码只是软件开发的其中一个方面&#xff0c;编写可靠的软件和产出有价值的代码更加重…

树链剖分+线段树 单点修改 区间求和 模板

马上要去西安打邀请赛了&#xff0c;存下板子 首先是vector存图的&#xff1a; #include<bits/stdc.h> using namespace std; #define ll long long #define lson l,m,rt<<1 #define rson m1,r,rt<<1|1 #define mid int m (l r) >> 1 const int M …

koa --- seesion实现登录鉴权

koa vue session 实现一个简单的登录逻辑 /login component/login-session.html <!DOCTYPE html><head><script src"https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script><script src"https://unpkg.com/axios/dist/axios.…

BZOJ2216: [Poi2011]Lightning Conductor

第一道此类的题&#xff0c;所以这是一篇假的博客&#xff0c;定理不会证明不理性 也不一定对 我是从这篇博客看的 很显然是让你求 p[i] max{a[j] sqrt(i - j)} - a[i] 就是 max{a[j] sqrt(|i - j|)} 这是一个 1D/1D 动态规划 考虑对于绝对值的情况不好做&#xff0c;那就…