首页 > 其他分享 >聊聊事件循环

聊聊事件循环

时间:2024-09-18 18:36:32浏览次数:10  
标签:setTimeout setInterval 回调 队列 任务 循环 事件 聊聊 执行

事件循环
> js 是单线程,js 引擎在执行时的原则:获取任务、执行任务。反复重复此过程,直到没有可执行的任务为止。任务分为同步任务和异步任务。异步任务分为宏任务和微任务。
- js 处理异步主要有微任务(microTask)和 宏任务 (macroTask),而从开始执行一个宏任务–>执行完这个宏任务中所有同步代码—>清空当前微任务队列中所有微任务—> UI 渲染 。 这便是完成了一个事件循环(Tick), 然后开始执行下一个宏任务(相当于下一轮循环)。
宏任务
- script(整体代码) - setTimeout、setInterval - setImmediate(node) - requestAnimationFrame - I/O - DOM
微任务
- process.nextTick(node) - Promise.then、Promise.catch、Promise.finally - MutationObserver(监听 dom 变化)
如何执行
> 首先执行宏任务,在执行宏任务过程中,遇到同步代码立即推入执行栈,遇到微任务追加到微任务队列,遇到宏任务追加到宏任务队列,等待同步任务执行完成后,将微任务队列中的任务依次执行直到微任务队列为空,到此循环结束,下一个循环从宏任务开始执行宏任务重复以上操作。
事件循环机制(node)
- timers 阶段:这个阶段执行 timer(setTimeout、setInterval)的回调 - 定时器检测阶段(timers):本阶段执行 timer 的回调,即 setTimeout、setInterval 里面的回调函数 - I/O 事件回调阶段(I/O callbacks):执行延迟到下一个循环迭代的 I/O 回调,即上一轮循环中未被执行的一些 I/O 回调 - 闲置阶段(idle, prepare):仅系统内部使用 - 轮询阶段(poll):检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞 - 检查阶段(check):setImmediate() 回调函数在这里执行 - 关闭事件回调阶段(close callback):一些关闭的回调函数,如:socket.on('close',...)
setTimeout 与 setInterval 时间不准如何解决
> 定时器指定的时间间隔,表示的是何时将定时器的代码添加到消息队列,而不是何时执行代码。所以真正何时执行代码的时间是不能保证的,取决于何时被主线程的事件循环取到,并执行。setTimeout 低于 4ms 时间间隔为 4ms(不同浏览器有不同的最小时间设定)
setTimeout(js 单线程阻塞,由于前一个任务耗时过长倒是定时器无法立即放入到事件队列)
- 确保回调函数尽量短,避免时间的计算或阻塞操作过长。 - 可以使用 requestAnimationFrame 代替 setInterval - 使用 setImmediate 代替 setTimeout
setInterval(累计误差、单线程阻塞)
- 使用 setTimeout 代替 setInterval - 计算每次回调执行的时间
为什么使用 setTimeout 代替 setInterval
- setInterval,某些时间会被跳过(比如上个还是队列中就会被跳过) - setInterval 可能多个定时器连续触发(上一个在执行,下一个进入队列时间,上一个执行过长下一个直接执行) - setTimeout 每次产生的任务直接 push 到任务队列,不会出现连续触发

标签:setTimeout,setInterval,回调,队列,任务,循环,事件,聊聊,执行
From: https://www.cnblogs.com/zhoulongfei/p/18419073

相关文章

  • Qt 事件处理
    classQtWidgetsApplication1:publicQMainWindow{Q_OBJECTpublic:QtWidgetsApplication1(QWidget*parent=nullptr);~QtWidgetsApplication1();private:Ui::QtWidgetsApplication1Classui;publicslots:voidchangelabel();};QtWi......
  • Spring Boot解决循环依赖
    一、前言环依赖是指两个或者多个bean互相依赖对方,从而形成一个闭环。例如:BeanA依赖于BeanB,而BeanB又依赖于BeanA。可能会导致Spring在尝试创建这些bean实例时出现问题,因为他们互相等待对方被创建,最终导致应用程序无法启动。Spring是如何发现这种循环依赖的问题的呢?通过依赖图来......
  • VUE框架CLI组件化组件绑定自定义事件时回调函数的this对象------VUE框架
    <template> <div> <!--内置函数的实现步骤--> <!--提供事件源,给事件源绑定事件,编写回调函数,将回调函数和事件进行绑定--> <!--等待事件的触发,事件触发执行回调函数--> <!--组件的自定义事件实现步骤--> <button@click="Hello()">你好</button> <!--给Us......
  • Spring 的循环依赖
    在Spring中,循环依赖是指两个或多个Bean相互依赖,导致在创建过程中出现了依赖死锁的问题。为了解决循环依赖,Spring引入了三级缓存机制。了解为什么需要三级缓存机制,首先要明白循环依赖是如何发生的,以及两级缓存为什么不足够。一、循环依赖是什么?假设有两个BeanA和B:A......
  • JavaScript 中循环数据、改变数据的几种方法
    将数组对象中的属性值取出并组成新的数组letarr=[{name:"张三",age:"1",sex:"男",grade:11},{name:"李四",age:"2",sex:"男",grade:12},{name:"王五",age:"3",sex:"男",gra......
  • 10_Python流程控制_循环
    循环循环是控制程序重复执行特定代码块的关键结构。Python提供了几种不同的循环结构,以满足不同的编程需求。While循环while循环会重复执行一个代码块,只要指定的条件为真。适用情况:不清楚具体的循环次数,或者当条件一直为真时一般用while。注意:条件中的变量在while迭代......
  • 什么是事件驱动
    什么是事件驱动?事件驱动是一种编程和系统设计模式,核心思想是:系统的运作是通过事件来驱动的,系统各个部分对事件作出反应并执行相应操作。事件可以是任何系统内部或外部触发的操作,比如用户点击按钮、网络请求、文件读取完成等。在事件驱动架构中,程序不会按顺序执行一连串预......
  • VUE框架CLI组件化组件解绑事件实现------VUE框架
    <template> <div> <!--内置函数的实现步骤--> <!--提供事件源,给事件源绑定事件,编写回调函数,将回调函数和事件进行绑定--> <!--等待事件的触发,事件触发执行回调函数--> <!--组件的自定义事件实现步骤--> <button@click="Hello()">你好</button> <!--给Us......
  • 含光热电站、有机有机朗肯循环、P2G的综合能源优化调度(Matlab代码实现)
    ......
  • 聊聊企业驻场外包信息安全管理
    目前许多公司出于降本增效的考虑,大量使用服务外包的形式,通常根据外包人员是否入驻服务企业营业场所又可将外包分为驻场和非驻场两类。按照服务类型分又可以划分为安全服务类、开发测试类、咨询规划类、业务支持类等。一:驻场外包人员风险:数据泄露风险:外包人员可能由于培训不足缺......