了解node.js事件循环

时间: 2018-06-08阅读: 1436标签: node

node.js的第一个基本论点是I / O的性能消耗是很昂贵:



因此,使用当前编程技术的最大浪费来自于等待I / O完成。有几种方法可以处理性能影响(来自Sam Rushing)):

  • 同步:您一次处理一个请求,每个请求依次处理。优点:简单。缺点:任何一个请求都需要等待上一个请求的完成后才执行。

  • 启动一个新的进程:你使用一个新的进程来处理每个请求。优点:容易。缺点:不能很好地扩展,数百个连接意味着数百个进程。 fork()是Unix程序员的锤子。因为它是可用的,所以每个问题看起来都像一个钉子。这通常是矫枉过正

  • 线程:启动一个新线程来处理每个请求。优点:简单,并且比使用fork更亲切,因为线程通常具有更少的开销。 缺点:您的机器可能没有线程,并且线程化编程可能会变得非常复杂,并且担心控制对共享资源的访问。

第二个基础论点是线程每连接的内存很贵:[例如该图表显示了与Nginx相比,Apache吸收内存的每个人都清楚]

Apache是​​多线程的:它为每个请求产生一个线程(或进程,它依赖于conf)。随着并发连接数量的增加以及需要更多线程来为多个同时的客户端服务,您可以看到这种开销如何消耗内存。 Nginx和Node.js不是多线程的,因为线程和进程会带来沉重的内存成本。它们是单线程的,但是基于事件。这消除了数千个线程/进程通过处理单个线程中的多个连接而产生的开销。


Node.js为您的代码保留单个线程...

它确实是一个单线程运行:你不能执行任何并行代码;例如做一个“sleep”会阻塞服务器一秒钟:js while(new Date().getTime()< now + 1000){// do nothing}所以当这段代码运行时,node.js不会响应来自客户端的任何其他请求,因为它只有一个执行代码的线程。或者如果你有一些CPU密集的代码,比如说调整图像大小,那么它仍然会阻止所有其他的请求。


..然而,除了你的代码,所有东西都是并行运行

在单个请求中没有办法让代码并行运行。但是,所有的I / O都是偶数并且是异步的,所以下面不会阻塞服务器:[codesyntax lang =“JavaScript”]

 c.query(
   'SELECT SLEEP(20);',
   function (err, results, fields) {
     if (err) {
       throw err;
     }
     res.writeHead(200, {'Content-Type': 'text/html'});
     res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');
     c.end();
    }
);

如果你在一个请求中这样做,其他请求可以在数据库运行时进行处理。


为什么要这样处理?我们什么时候从同步到异步/并行执行?

同步执行很好,因为它简化了编写代码(与线程相比,并发问题有导致WTF的倾向)。

在node.js中,你不应该担心后端会发生什么情况:只要在做I / O时使用回调;并确保您的代码永远不会中断,并且执行I / O不会阻止其他请求,而不会导致每个请求的线程/进程成本(例如Apache中的内存开销)。

拥有异步I / O是很好的,因为I / O的更高效,我们应该做更好的事情,而不仅仅是等待I / O。


事件循环是“处理和处理外部事件并将其转换为回调调用的实体”。因此,I / O调用是Node.js可以从一个请求切换到另一个请求的点。在I / O调用中,您的代码会保存回调并将控制权返回给node.js运行时环境。当数据实际可用时,稍后调用回调。

当然,在后端,有数据库访问和流程执行的线程和进程。然而,这些并没有明确暴露给你的代码,所以除了知道I / O交互例如与数据库或与其他进程的异步从每个请求的角度来看,因为这些线程的结果通过事件循环返回到您的代码。与Apache模型相比,线程和线程开销较少,因为每个连接都不需要线程;当你绝对肯定必须有别的东西并行运行时,即使这样管理也是由Node.js来处理的。

除I / O调用外,Node.js预计所有请求都会很快返回;例如应将CPU密集型工作分解到另一个可与事件交互的进程,或使用WebWorkers之类的抽象。这(显然)意味着如果没有另一个线程与您通过事件交互的背景进行交互,则无法并行化代码。基本上,所有发出事件的对象(例如,EventEmitter的实例)都支持异步的偶数交互,并且你可以用这种方式与阻止代码进行交互,例如,使用所有这些都是Node.js中的EventEmitter的文件,套接字或子进程。多核可以使用这种方法完成;另请参阅:node-http-proxy。

内部实施

在内部,node.js依靠libev来提供事件循环,这是libeio的补充,它使用池化线程来提供异步I / O。要了解更多信息,请查看libev文档


那么我们如何在Node.js中进行异步?

Tim Caswell在他精彩的演讲中描述了这些模式:

  • 一流的功能。例如。我们将函数作为数据传递,随机播放并在需要时执行它们。
  • 功能组成。也称为具有匿名函数或闭包,在事件发生在偶数I / O之后执行。
原文链接: blog.mixu.net 
翻译来源:www.zcfy.cc 
站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/867

NodeJS有难度的面试题,你能答对几个?

加载模块时,为什么每个模块都有__dirname,__filename属性呢,new Module的时候我们看到1.1部分没有这两个属性的,那么这两个属性是从哪里来的

node modules是什么?

在node.js中modules(模块)与文件是一一对应的,也就是说一个node.js文件就是一个模块,文件内容可能是我们封装好的一些JavaScript方法、JSON数据、编译过的C/C++拓展等,在关于node.js的误会提到过node.js的架构

Node.js FS模块方法速查

所有文件操作提供同步和异步的两种方式,本笔记只记录异步的API,异步方式其最后一个参数是回调函数。回调函数的第一个参数往往是错误对象,如果没有发生参数,那么第一个参数可能是null或者undefinded。

前端学nodejs有什么用处?

Node.js是一个基于 Chrome V8 引擎的 JavaScript 运行环境,一个基于Chrome JavaScript运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。

深入解析Node.js Event Loop各阶段

今天小编就为大家分享一篇关于Node.js Event Loop各阶段讲解,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。timer阶段处理setTimeout于setInterval回调,开始处理的时机与poll阶段有关联。

关于 Node.js 里 ES6 Modules 的一次更新说明

关于 Node.js 里 ES6 Modules 的一次更新说明,总结来说:CommonJS 与 ES6 Modules 之间的关键不同在于代码什么时候知道一个模块的结构和使用它。

mocha自动化测试程序:node.js测试框架Mocha源码分析

Mocha.js是被广泛使用的Javascript测试框架,在浏览器和Node环境都可以使用。Mocha提供TDD和BDD的测试接口。 Mocha提供了:断言单元测试,可以进行功能性测试,同步代码测试,异步代码测试

Node.js 15 正式版发布

前两天,Node.js官方发布了Node.js 15的正式版本,Node.js 15 将替代 Node.js 14 成为当前的的稳定发行版,后者将在本月晚些时候升级为 LTS(长期支持)版本。如果大家想体验下Node.js 15 的最新功能

Node 最古老的 npm 包 request 将被废弃

相信 Node.js 开发者对 Request 都不会陌生,这是一个 Node.js 模块,以 npm 包的形式提供,是一个简单的 HTTP 客户端,通过它可方便地实现 HTTP 请求。可以看到,request 的最新版本是 2.88.0

nodejs 文本逐行读写功能的实现

利用nodejs实现:逐行读写(从一个文件逐行复制到另外一个文件);逐行读取、处理和写入(读取一行,处理后,写入另一个文件)1.所需要的模块: fs,os,readline。功能的实现:readWriteFileByLine.js,功能的调用:index.js

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!