从医生看病和快餐店点餐理解Node.js的事件驱动
第一个例子是关于医生看病。
在美国去看医生,需要填写大量表格,比如保险、个人信息之类,传统的基于线程的系统(thread-based system),接待员叫到你,你需要在前台填写完成这些表格,你站着填单,而接待员坐着看你填单。你让接待员没办法接待下一个客户,除非完成你的业务。
想让这个系统能运行的快一些,只有多加几个接待员,人力成本需要增加不少。
基于事件的系统(event-based system)中,当你到窗口发现需要填写一些额外的表格而不仅仅是挂个号,接待员把表格和笔给你,告诉你可以找个座位填写,填完了以后再回去找他。你回去坐着填表,而接待员开始接待下一个客户。你没有阻塞接待员的服务。
你填完表格,返回队伍中,等接待员接待完现在的客户,你把表格递给他。如果有什么问题或者需要填写额外的表格,他给你一份新的,然后重复这个过程。
这个系统已经非常高效了,几乎大部分医生都是这么做的。如果等待的人太多,可以加入额外的接待员进行服务,但是肯定要比基于线程模式的少得多。
第二个例子是快餐店点餐。
在基于线程的方式中(thread-based way)你到了柜台前,把你的点餐单给收银员或者给收银员直接点餐,然后等在那直到你要的食物准备好给你。收银员不能接待下一个人,除非你拿到食物离开。想接待更多的客户,容易!加更多的收银员!
当然,我们知道快餐店其实不是这样工作的。他们其实就是基于事件驱动方式,这样收银员更高效。只要你把点餐单给收银员,某个人已经开始准备你的食物,而同时收银员在进行收款,当你付完钱,你就站在一边而收银员已经开始接待下一个客户。在一些餐馆,甚至会给你一个号码,如果你的食物准备好了,就呼叫你的号码让你去柜台取。关键的一点是,你没有阻塞下一个客户的订餐请求。你订餐的食物做好的事件会导致某个人做某个动作(某个服务员喊你的订单号码,你听到你的号码被喊到去取食物),在编程领域,我们称这个为回调(callback function)。
Node.Js做了什么工作呢?
传统的web server多为基于线程模型。你启动Apache或者什么server,它开始等待接受连接。当收到一个连接,server保持连接连通直到页面或者什么事务请求完成。如果他需要花几微妙时间去读取磁盘或者访问数据库,web server就阻塞了IO操作(这也被称之为阻塞式IO).想提高这样的web server的性能就只有启动更多的server实例。
相反的,Node.Js使用事件驱动模型,当web server接收到请求,就把它关闭然后进行处理,然后去服务下一个web请求。当这个请求完成,它被放回处理队列,当到达队列开头,这个结果被返回给用户。这个模型非常高效可扩展性非常强,因为webserver一直接受请求而不等待任何读写操作。(这也被称之为非阻塞式IO或者事件驱动IO)
考虑下面这个过程:
1,你用浏览器访问nodejs服务器上的"/about.html"
2,nodejs服务器接收到你的请求,调用一个函数从磁盘上读取这个文件。
3,这段时间,nodejs webserver在服务后续的web请求。
4,当文件读取完毕,有一个回调函数被插入到nodejs的服务队列中。
5,nodejs webserver运行这个函数,实际上就是渲染(render)了about.html页面返回给你的浏览器。
好像就节省了几微秒时间,但是这很重要!特别是对于需要相应大量用户的web server。
Dan York原文:Node.js, Doctor’s Offices and Fast Food Restaurants – Understanding Event-driven Programming
从医生看病和快餐店点餐理解Node.js的事件驱动的更多相关文章
- 深入理解Node.js基于事件驱动的回调
回调和异步调用的关系 首先明确一点,回调并非是异步调用,回调是一种解决异步函数执行结果的处理方法.在异步调用,如果我们希望将执行的结果返回并且处理时,可以通过回调的方法解决.为了能够更好的区分回调和异 ...
- 理解Node.js事件驱动编程
Node.js现在非常活跃,相关生态社区已经超过Lua(基本上比较知名的功能都有nodejs模块实现). 但是我们为何要使用Node.Js?相比传统的webserver服务模式,nodejs有什么优点 ...
- 理解Node.js的事件轮询
前言 总括 : 原文地址:理解Node.js的事件轮询 Node小应用:Node-sample 智者阅读群书,亦阅历人生 正文 Node.js的两个基本概念 Node.js的第一个基本概念就是I/O操 ...
- 深度理解Node.js单线程模型
Node.js采用 事件驱动 和 异步I/O 的方式,实现了一个单线程.高并发的运行时环境,而单线程就意味着同一时间只能做一件事,那么Node.js如何利用单线程来实现高并发和异步I/O?本文将围绕这 ...
- 方便大家学习的Node.js教程(一):理解Node.js
理解Node.js 为了理解Node.js是如何工作的,首先你需要理解一些使得Javascript适用于服务器端开发的关键特性.Javascript是一门简单而又灵活的语言,这种灵活性让它能够经受住时 ...
- 深入理解Node.js中的垃圾回收和内存泄漏的捕获
深入理解Node.js中的垃圾回收和内存泄漏的捕获 文章来自:http://wwsun.github.io/posts/understanding-nodejs-gc.html Jan 5, 2016 ...
- 如何理解Node.js和JavaScript的关系
一.Javascript的引擎 浏览器一般有两个引擎,一个是Html引擎,一个是脚本引擎. JavaScript是一种脚本语言,最初用于浏览器的动态显示,方便操作页面数据和内容.但实际上,它也可以在浏 ...
- 理解 Node.js 里的 process.nextTick()
有很多人对Node.js里process.nextTick()的用法感到不理解,下面我们就来看一下process.nextTick()到底是什么,该如何使用. Node.js是单线程的,除了系统IO之 ...
- 理解Node.js(译文)
前言 总括 :这篇文章十分生动形象的的介绍了Node,满足了读者想去了解Node的需求.作者是Node的第一批贡献者之一,德国前端大神.译者觉得作者的比喻很适合初学者理解Node,特此翻译. 译者 : ...
随机推荐
- 【转】Maven实战(八)---模块划分
本博文出自于:http://blog.csdn.net/liutengteng130/article/details/47000217 感谢! 为了防止传递依赖,我们各个模块之间尽量用直接依赖的 ...
- Spark SQL概念学习系列之如何使用 Spark SQL(六)
val sqlContext = new org.apache.spark.sql.SQLContext(sc) // 在这里引入 sqlContext 下所有的方法就可以直接用 sql 方法进行查询 ...
- HDU 5816 Hearthstone (状压DP)
Hearthstone 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an onlin ...
- CodeForces 682E Alyona and Triangles (计算几何)
Alyona and Triangles 题目连接: http://acm.hust.edu.cn/vjudge/contest/121333#problem/J Description You ar ...
- Oracle-11g-R2(11.2.0.3.x)RAC Oracle Grid & Database 零宕机方式回滚 PSU(自动模式)
回滚环境: 1.源库版本: Grid Infrastructure:11.2.0.3.15 Database:11.2.0.3.15 2.目标库版本: Grid Infrastructure:11.2 ...
- [0.0]Analysis of Baidu search engine
Rencently, my two teammates and I is doing a project, a simplified Chinese search engine for childre ...
- 一个非常标准的Java连接Oracle数据库的示例代码
最基本的Oracle数据库连接代码(只针对Oracle11g): 1.右键项目->构建路径->配置构建路径,选择第三项“库”,然后点击“添加外部Jar”,选择“D:\Oracle\app\ ...
- 备份spfile 中的一个误区
某书载在备份控制文件的时候,也会自动的备份初始化参数文件,抱着愚钝的 完事亲力亲为的态度,做了如下的小验证. RMAN> list backup of controlfile; specific ...
- IIS功能查看、配置
#获取所有IIS功能列表: get-webconfiguration -filter /system.webserver #查看目录浏览功能的配置信息:Get-WebConfiguration -fi ...
- Hash Table构建
get-item e:\test\* |format-table @{name="aa";expression={$_.name.tostring().split(".& ...