了解node.js事件循环

时间: 2018-06-08阅读: 311标签: 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 

虎牙直播弹幕转换字幕格式 基于Node.js 的 huya-danmu

首先安装nodejs运行环境, 从 http://nodejs.cn/download/ 下载对应的版本, 安装 huya-danmu 模块, https://github.com/BacooTang/huya-danmu 有详细的安装方法,参照 huya-danmu 模块中 test.js 编写 huya.js 新文件,录视频的同时运行 huyaDanmu 批处理命令, 就不用在调整时间轴;

NodeJS沙盒逃逸研究

在这篇文章中,我们将探讨如何使用解释器的内部结构来逃离NodeJS沙箱。Node.js不是一个JavaScript框架,不同于CakePHP、Django、Rails。Node.js更不是浏览器端的库,不能与jQuery、ExtJS相提并论。

Node.js FS模块方法速查

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

如何让 node 运行 es6 模块文件,及其原理

最新版的 node 支持最新版 ECMAScript 几乎所有特性,但有一个特性却一直到现在都还没有支持,那就是从 ES2015 开始定义的模块化机制。而现在我们很多项目都是用 es6 的模块化规范来写代码的,包括 node 项目

nodejs的jekins部署

gitlab项目仓库给jekins服务器分配一个账号develop权限用于拉取代码。分支为master。jekins配置打包脚本。思路就是拉取最新代码后,安装相关依赖。删除旧打包文件。新建打包文件项目名.tar.gz。通过SSH传输打包文件项目名.tar.gz到测试服务器指定目录。

NodeJs实现简单的爬虫

爬虫,是一种按照一定的规则,自动地抓取网页信息的程序或者脚本;利用NodeJS实现一个简单的爬虫案例,脚本所用到的nodejs模块。express 用来搭建一个服务,将结果渲染到页面, swig模板引擎,cheerio用来抓取页面的数据

node.js反向代理的实现

在实际工程开发中,会有前后端分离的需求。使用node.js反向代理的目的:实现前后端分离,前端减少路径请求的所需的路由文件;通过http-proxy-middleware中间件、Http Proxy 模块这2种方式实现node.js的反向代理

使用 Node.js 开发简单的脚手架工具

像我们熟悉的 vue-cli,react-native-cli 等脚手架,只需要输入简单的命令 vue init webpack project,即可快速帮我们生成一个初始项目。在实际工作中,我们可以定制一个属于自己的脚手架,来提高自己的工作效率。

Kotlin + Node.js 搭建教程

Kotlin是JetBrains推出的一款语言, 相比Java有更简洁的语法, 能编译为Java Class, 也能编译为JavaScript Node.js则是可以运行在服务端的JavaScript, 这里把二者结合, 搭建一个用Kotlin编写的服务端应用

用node探究http缓存

用node搞web服务和直接用tomcat、Apache做服务器不太一样, 很多工作都需要自己做。缓存策略也要自己选择,虽然有像koa-static,express.static这些东西可以用来管理静态资源,但是为了开发或配置时更加得心应手,知其所以然,有了解http缓存的必要。另外,http缓存作为一个前端优化的一个要点,也应该有所了解。

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

广告合作文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯