事件循环

Javascript是单线程的,但是nodejs通过事件循环的方式实现了非阻塞的IO。

Javascript主线程通过将发起的IO操作封装请求对象传递给IO线程池,主线程继续完成自己接下来的工作。IO线程池中利用空闲的线程完成IO操作后,会进入事件循环阶段阶段,在此阶段取出IO结果和回调函数进行执行

事件循环的阶段

每个阶段都有一个需要执行的回调函数的先入先出(FIFO)队列。同时,每个阶段都是特殊的,基本上,当事件循环进行到某个阶段时,会执行该阶段特有的操作,然后执行该阶段队列中的回调,直到队列空了或者达到了执行次数限制。这时候,事件循环会进入下一个阶段,循环往复。

阶段总览

  • 计时器(timers):本阶段执行setTimeout() 和 setInterval() 计划的回调
  • I/O 回调: 执行几乎全部发生异常的 close 回调, 由定时器和setImmediate()计划的回调;
  • 空闲,预备(idle,prepare):只内部使用;
  • 轮询(poll): 获取新的 I/O 事件;nodejs这时会适当进行阻塞;
  • 检查(check): 调用 setImmediate() 的回调;
  • close callbacks: 例如 socket.on('close', ... );

阶段细节(着重 timer, poll, check)

定时器(timers)

定时器的用途是让指定的回调函数在某个阈值后会被执行,具体的执行时间并不一定是那个精确的阈值。定时器的回调会在制定的时间过后尽快得到执行,然而,操作系统的计划或者其他回调的执行可能会延迟该回调的执行。

注:从技术上来看,轮询阶段控制了定时器的执行时机。

例如,你设定了在100ms后执行某个操作,然后脚本开始执行一个需要95ms的文件读取操作。当文件读取完成时,轮询阶段加入了回调函数,假设回调函数执行10ms完成,这时poll阶段回调队列清空完成了,此时才会去执行timer阶段回调。

轮询(poll)

轮询阶段有两个主要功能:

  1. 执行已经到时的定时器脚本
  2. 处理轮询队列中的事件。

当事件循环进入到轮询阶段却没有发现定时器时:

  • 如果轮询队列非空,事件循环会迭代回调队列并同步执行回调,直到队列空了或者达到了上限(根据操作系统的不同而设定的上限)
  • 如果轮询队列是空的
    • 如果有setImmediate()定义了回调,那么事件循环会终止轮询阶段并进入检查阶段去执行定时器回调;
    • 如果没有setImmediate(),事件回调会等待回调被加入队列并立即执行。

一旦轮询队列空了,事件循环会查找已经到时的定时器。如果找到了,事件循环就回到定时器阶段去执行回调。

检查(check)

这个阶段允许回调函数在轮询阶段完成后立即执行。如果轮询阶段空闲了,并且有回调已经被 setImmediate() 加入队列,事件循环会进入检查阶段而不是在轮询阶段等待。

setImmediate() vs setTimeout()

这两个很相似,但调用时机会的不同会导致它们不同的表现。

  • setImmediate() 被设计成一旦轮询阶段完成就执行回调函数;
  • setTimeout() 规划了在某个时间值过后执行回调函数;

这两个执行的顺序会因为它们被调用时的上下文而有所不同。如果都是在主模块调用,那么它们会受到进程性能的影响

但是如果把它们放进 I/O 循环中,setImmediate() 的回调总是先执行,setImmediate() 比 setTimeout() 优势的地方是 setImmediate() 在 I/O 循环中总是先于任何定时器,不管已经定义了多少定时器。

Nodejs事件循环相关推荐

  1. nodejs 事件循环机制

    nodejs事件循环机制 nodejs是基于v8引擎的JavaScript运行时.(注意nodejs不是一门新的编程语言) nodejs是基于libuv实现 异步非阻塞式i/o 操作的.而事件循环是n ...

  2. 剖析nodejs的事件循环

    本文首发在github,感兴趣请点击此处 nodejs是单线程执行的,同时它又是基于事件驱动的非阻塞IO编程模型.这就使得我们不用等待异步操作结果返回,就可以继续往下执行代码.当异步事件触发之后,就会 ...

  3. hook 循环点击事件用哪个_JS 事件循环 event loop,看完你可以答对 90% 的事件循环题...

    本文不保证能说明透彻,因为它本来就存在着混乱,但力求讲到点子上. 比较下面这几个的执行顺序setTimeout setInterval setImmediate (nodejs 支持, new Pro ...

  4. 八七、Node.js事件循环与多进程

    nodejs事件循环与多进程 why 事件循环对于深入理解nodejs异步至关重要 fs, net,http,events 事件循环是企业面试中的最高频考题之一 能驾驭nodejs多进程是一名资深前端 ...

  5. 浏览器和node事件循环

    什么是事件循环 每一个浏览器都至少有一个事件循环,一个事件循环至少有一个任务队列.循环指的是其永远处于一个"无限循环"中.不断将注册的回调函数推入到执行栈 浏览器的事件循环标准是由 ...

  6. nodejs的事件循环1

    JavaScript的学习零散而庞杂,因此很多时候我们学到了一些东西,但是却没办法感受到自己的进步,甚至过了不久,就把学到的东西给忘了.为了解决自己的这个困扰,在学习的过程中,我一直试图在寻找一条核心 ...

  7. 【nodejs原理源码赏析(7)】【译】Node.js中的事件循环,定时器和process.nextTick

    [摘要] 官网博文翻译,nodejs中的定时器 示例代码托管在:http://www.github.com/dashnowords/blogs 原文地址:https://nodejs.org/en/d ...

  8. nodejs ref操作_nodejs事件和事件循环详解

    简介 上篇文章我们简单的介绍了nodejs中的事件event和事件循环event loop.本文本文将会更进一步,继续讲解nodejs中的event,并探讨一下setTimeout,setImmedi ...

  9. nodejs事件和事件循环简介

    文章目录 简介 事件 事件循环 事件循环的阻塞 事件循环举例 栈和消息队列 作业队列和promise process.nextTick() setImmediate() setInterval() 简 ...

最新文章

  1. C语言 数据类型(就做个笔记总结)
  2. 轻轻一扫,立刻扣款,付款码背后的原理你不想知道吗?
  3. eclipse如何设置去除全部断点的快捷键
  4. 2021-07-07
  5. zabbix的安装配置
  6. [ACM] hdu 1754 I Hate It (线段树,单点更新)
  7. 学习笔记(21):Python网络编程并发编程-队列的使用
  8. flask中关于endpoint端点、url_map映射、view_func视图函数,view_functions、及视图函数名是否何以相同的问题?
  9. 双盘转子动力学仿真c语言程序,递归牛顿欧拉(正)动力学仿真
  10. oeasy教您玩转vim - 38 - # 配合移动
  11. 投稿流程以及审稿状态
  12. Apache DolphinScheduler征稿 — 小Demo轻松入门DolphinSchedule大数据调度工具
  13. mSystems:苏晓泉、徐健等发布全球微生物组结构和功能搜索平台2.0
  14. tabindex的使用
  15. 富芮坤蓝牙FR801xH开发环境搭建
  16. 抢红包代码 php,ASP.NET代码轻松实现微信抢红包
  17. 【IPFS周报-101】查看胡安、V神,诸多大佬的峰会演讲
  18. vue背景图片怎么用变量表示?
  19. STL——空间配置器剖析(一级空间配置器、二级空间配置器的本质及运用场合,是如何用内存池去管理的)
  20. 在日常使用中关于英特尔睿频加速的优劣分析(附带关闭睿频加速的两种方法)

热门文章

  1. javascript基础系列:函数(三)
  2. mysql-mmm_MySQL-MMM高可用群集
  3. 北林oj-算法设计与分析-Line up in the canteen(两种解法,附思路)
  4. PAT乙级 1094 谷歌的招聘(柳婼代码,测试点1、2、4、5分析)
  5. java socket 读取文件_Java中Socket下载一个文本文件
  6. c 读取url中的html文本,如何使用Guzzlehttp获取给定url的html内容
  7. selenium java项目_1)selenium+ java集成,待深度项目流程应用
  8. 景霄讲解Python部分内部实现
  9. python调用jenkinsAPI构建jenkins,并传递参数
  10. Vue路由 --登录状态的判断