主线程从"任务队列"中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。下面本篇文章就来带大家掌握Node.js中的eventloop,希望对大家有所帮助!
其实在前面的文章我也讲述过浏览器中的eventloop。然而在NodeJs中的eventloop与浏览器的是有区别的。对于写nodejs的人来说掌握eventloop是一项很重要的技能。因为这意味着你不仅是会写js,而对NodeJs也是有研究的。
为什么要有eventloop?
我们知道NodeJs的本质是把浏览器的v8搬到了操作系统中运行,因此也把浏览器的事件循环拿过来了。可是为什么会出现eventloop这样的设计呢?
从历史原因上来看,js在设计时只是一门很简单的为了在页面上操作一下dom的语言(相信大家都听过js只用了10天就设计出来的故事)。出于这个目标,我们当然希望js的运行尽可能的简单,轻量,有多轻呢?轻到js的渲染引擎是在一个线程中运行的。
那么问题来了如果是在一个线程上运行js,当代码是线性的时候,当然是没有问题的。但在页面上,我们需要用户的交互,而这些交互是不知道为什么时候发生的。那js要怎么处理?如果眼前有正在运行的代码,一个用户交互进来之后,程序该怎么反应?如果先处理用户的交互,那原来的程序就会被暂停(也就是阻塞)。为了避免这种阻塞,js采用了一个办法,就是用一个消息队列,来存放这种用户交互。等所有的程序跑完之后,再去消息队列中拿交互事件,然后执行。这样就解决了阻塞的问题了。
浏览器的eventloop
我们都知道浏览器在浏览页面的时候,用户交互是随时可能发生的,为了可以即时响应用户。js是不会关闭的,他会不停的循环。大致如下:
向消息队列拿任务-->执行任务-->执行完毕--> 向消息队列拿任务--> ....
当然我们在之前的事件循环文章中讲过,为了给不同的异步任务分类,在事件循环中其实是有宏任务和微任务的区分的。他们的执行大致为
向消息队列拿微任务-->执行微任务-->微任务执行完毕--> 向消息队列拿宏任务-->执行宏任务-->宏任务执行完毕-->向消息队列拿微任务-->...
NodeJs的eventloop
node的事件循环其实大致思路跟在浏览器上的是相似的,但nodeJs对不同的宏任务又作出了不同时期的区分。下面是官方的流程图:
可以看到nodeJs中每次事件循环被分成了具体的6个时期,每个时期会用指定的宏任务。然后在每个时期的宏任务执行之前,会优先执行完微任务队列。
总览
timers | 执行由setTimeout() 和 setInterval() 触发的回调 |
---|---|
pending callbacks | 执行延迟到下一个循环迭代的I / O回调 |
idle, prepare | 只在内部使用,开发者可以不关注 |
poll | 检索新的I / O事件;执行I / O相关的回调(会执行几乎所有的回调,除了 close callbacks 以及 timers 调度的回调和 setImmediate() 调度的回调,在恰当的时机将会阻塞在此阶段) |
check | 执行setImmediate() |
close callbacks | 比如socket.on('close', ...) |
其实通过上述表格,我们已经很清晰知道整个事件循环机制的执行顺序了。但可能大家还会有一些疑问。下面来详细讲一下。
pending callbacks
这个阶段其实是处理由于操作系统出错,导致一些本应在上次事件循环中执行的回调。例如一些TCP错误。因此这部分,开发者不能主动操作,是NodeJs的一些容错机制。
check
同样的,setImmediate是nodejs特有的api,他可以立即创建一个异步宏任务。不仅如此,nodejs在事件循环中还专门设了一个check时期,在这个时期会专门执行setImmediate的回调。甚至你可以在这个时期中如果不停的产生setImmediate回调,eventloop会优先处理。
close callbacks
这个时期处理关闭事件,如socket.on('close', ...) 等这样可以确保在一些通讯结束前,所有任务都完成了。
微任务在eventloop中
我们先来回顾浏览器与nodejs的差异:
宏任务:
任务 | 浏览器 | Node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout | ✅ | ✅ |
setInterval | ✅ | ✅ |
setImmediate | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
微任务:
任务 | 浏览器 | Node |
---|---|---|
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |
可以看到process.nextTick是nodejs特有的微任务,不仅如此,process.nextTick()的优先级高于所有的微任务,每一次清空微任务列表的时候,都是先执行 process.nextTick()
执行差异
不仅是任务类型上有差异,在执行上2个环境其实也有差异。在浏览器上执行任务的时候,每执行一个宏任务之前,需要先确保微任务队列执行完了。而在nodejs上是每个时期之前,先确保微任务队列执行完。也就是说在假如在timer时期,会先把所有setTimeout,setInterval的宏任务执行完。在执行完微任务,再进入下个时期。
注意:以上执行规则是在nodejs的v11版本之前的规则。在11版本之后nodejs的执行输出是跟浏览器一样的。
setImmediate() vs setTimeout()
setImmediate() 和 setTimeout()的执行先后顺序是不一定的,就是说如果你不停地执行以下代码,每次得到的结果可能是不一样的。
setTimeout(() => { console.log('timeout'); }, 0); setImmediate(() => { console.log('immediate'); });
其中的原因是程序对时间的处理是有误差的。在setTimeout方法中设置的时间,不一定是准确的。同时在回调触发时,也无法确认事件循环处在哪个时期,可能是timer,也可能是check。所有会有不同的结果。
总结
eventloop是js运行机制里的重点内容,对于NodeJs来说,eventloop的操作空间则更大。因为它被细分为不同的时期,从而让我们可能把逻辑进一步细化。同时利用nextTick的最高优先级,可以写出在浏览器无法实现的代码。因此对于深入NodeJs的开发者来说,eventloop往往是他们考察新人对NodeJs理解的第一步。
更多node相关知识,请访问:nodejs 教程!!
以上是一文带你了解Node.js中的eventloop的详细内容。更多信息请关注PHP中文网其他相关文章!

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

Dreamweaver Mac版
视觉化网页开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

Atom编辑器mac版下载
最流行的的开源编辑器

VSCode Windows 64位 下载
微软推出的免费、功能强大的一款IDE编辑器

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)