前言

总括

智者阅读群书,亦阅历人生

正文

Node.js的两个基本概念

Node.js的第一个基本概念就是I/O操作开销是巨大的:

所以,当前变成技术中最大的浪费来自于等待I/O操作的完成。有几种方法可以解决性能的影响:

  • 同步方式:按次序一个一个的处理请求。:简单;:任何一个请求都可以阻塞其他所有请求。
  • 开启新进程:每个请求都开启一个新进程。:简单;:大量的链接意味着大量的进程。
  • 开启新线程:每个请求都开启一个新线程。:简单,而且跟进程比,对系统内核更加友好,因为线程比进程轻的多;:不是所有的机器都支持线程,而且对于要处理共享资源的情况,多线程编程会很快变得太过于复杂。

第二个基本概念是每个连接都创建一个新线程是很消耗内存的(例如:你可以对比Nginx回想一下Apache内存耗尽的情景)。

Apache是多线程的:它为每个请求开启一个新的线程(或者是进程,这取决于你的配置),当并发连接增多时,你可以看看它是怎么一点一点耗尽内存的。Nginx和Node.js不是多线程的,因为线程的消耗太“重”了。它们两个是单线程、基于事件的,这就把处理众多连接所产生的线程/进程消耗给消除了。

单线程

确实只有一个线程:你不能并行执行任何代码,比如:下面的“sleep”将会阻塞sever1秒钟:

function sleep() {
var now = new Data().getTime();
while (new Date().getTime() < now + 1000) {
// do nothing
}
}
sleep();

但就我目前学习阶段而言,我觉得好多人对于所谓的node单线程是有误解的。实际上官方给出的“单线程”是具有误导性的。所谓的单线程是指你的代码只运行在一个线程上(好多地方都叫它主线程,实际上Javascript的浏览器运行环境不也是这么处理我们写的Javascript代码的嘛),而诸多任务的并行处理,就需要多线程了,如下图:

如上图,Node.js中的单线程之说指的就是这个主线程,这个主线程有一个循环结构,保持着整个程序(你写的代码)的运转。

事件轮询

其实上面我们所说的维持主线程运行的循环这部分就是"事件轮询",它存在于主线程中,负责不停地调用开发者编写的代码。但对开发者是不可见的。so...开发者编写的代码是怎样被调用的呢?看下图:

如上图,异步函数在执行结束后,会在事件队列中添加一个事件(遵循先进先出原则),主线程中的代码执行完毕后(即一次循环结束),下一次循环开始就在事件队列中"读取"事件,然后调用它所对应的回调函数(所以回调函数的执行顺序是不一定的)。如果开发者在回调函数中调用了阻塞方法(比如上文中的sleep函数),那么整个事件轮询就会阻塞,事件队列中的事件得不到及时处理。正因为这样,nodejs中的一些库方法均是异步的,也提倡用户调用异步方法。

var fs = require('fs');
fs.readFile('hello.txt', function (err, data) { //异步读取文件
  console.log("read file end");
});
while(1)
{
console.log("call readFile over");
}

如上代码,我们虽然使用了异步方法readfile读取文件,但read file end永远不会输出,因为代码始终在while循环中,下一次事件轮询始终没法开始,也就没法'读取'事件队列调用相应的回调函数了。

最后有一个Node-sample是博主平时积累的一些代码,包含注释,汇总成了一个小应用,还是可以看到学习的蛛丝马迹的。感兴趣的您可以看看。

后记

参考文章:

理解Node.js的事件轮询的更多相关文章

  1. Node.js的事件轮询Event Loop原理

    Node.js的事件轮询Event Loop原理解释 事件轮询主要是针对事件队列进行轮询,事件生产者将事件排队放入队列中,队列另外一端有一个线程称为事件消费者会不断查询队列中是否有事件,如果有事件,就 ...

  2. 对Node.JS的事件轮询(Event Loop)的理解

    title: Node.JS的事件轮询(event loop)的理解 categories: 理解 tags: Node JS 机制 当我们知道I/O操作和创建新线程的开销是巨大的! 网站延迟的开销 ...

  3. 理解JavaScript中的事件轮询

    原文:http://www.ruanyifeng.com/blog/2014/10/event-loop.html 为什么JavaScript是单线程 JavaScript语言的一大特点就是单线程,也 ...

  4. 理解 node.js 的事件循环

    node.js 的第一个基本观点是,I/O 操作是昂贵的: 目前的编程技术最大的浪费来自等待 I/O 操作的完成.有几种方法可以解决这些对性能的影响(来自Sam Rushing): 同步:依次处理单个 ...

  5. 理解Nodejs中的事件轮询机制

    我在看<了不起的Nodejs>一书,阻塞与非阻塞IO那一章我来回看了N遍,然后...还是没太看懂..于是我找到了这篇日志,写的是真的有点好啊..潸然泪下.. 原文:http://www.r ...

  6. node.js中的事件轮询Event Loop

    任务队列/事件队列 "任务队列"是一个事件的队列,IO设备完成一项任务,就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈" ...

  7. 【译】理解node.js事件轮询

    Node.js的第一个基本论点是I/O开销很大. 当前编程技术中等待I/O完成会浪费大量的时间.有几种方法可以处理这种性能上的影响: 同步:每次处理一个请求,依次处理.优点:简单:缺点:任何一个请求都 ...

  8. node.js事件轮询(1)

    事件轮询(引用) 事件轮询是node的核心内容.一个系统(或者说一个程序)中必须至少包含一个大的循环结构(我称之为"泵"),它是维持系统持续运行的前提.nodejs中一样包含这样的 ...

  9. Node.js的异步IO和事件轮询

     想象一下,以前我们在写程序时, 如果程序在I/O上阻塞了,当有更多请求过来时,服务器会怎么处理呢?在这种情景中通常会用多线程的方式.一种常见的实现是给每个连接分配一个线程,并为那些连接设置一个线程池 ...

随机推荐

  1. ArcGIS 10.5,打造智能的Web GIS平台

    2017年新年来临之际,ArcGIS 10.5正式发布.历经几个版本,ArcGIS 10.5已经革新为一个智能的以Web为中心的地理平台,推出更精细的分级授权.全新的i3S三维标准.大数据分析处理产品 ...

  2. Codeforces#364Div2

    A题: 题意:给定一些数,然后每两个组成一对,要求每对的和的大小相同,输出这样的组合 分析:直接模拟就行 #include <iostream> #include <cstdio&g ...

  3. [Unity Socket]在Unity中如何实现异步Socket通信技术

    在刚刚开发Unity项目的过程中,需要用到即时通信功能来完成服务器与客户端自定义的数据结构封装. 现在将部分主要功能的实现代码抽取出来实现了可以异步Socket请求的技术Demo. 客户端脚本Clie ...

  4. iOS8学习笔记2--autolayout

    iOS支持的设备如今已经具有了很多的尺寸,针对这些不同的尺寸每一个都做一个独立的APP肯定是不现实的,于是苹果在iOS8之后推出了autolayout和sizeclass,同时还有VFL界面设计语言 ...

  5. jQuery中$.get、$.post、$.getJSON和$.ajax的用法

    以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 一.jQuery中调用ajax的4种方法:$.get.$.post.$ge ...

  6. CodeForces 754D Fedor and coupons (优先队列)

    题意:给定n个优惠券,每张都有一定的优惠区间,然后要选k张,保证k张共同的优惠区间最大. 析:先把所有的优惠券按左端点排序,然后维护一个容量为k的优先队列,每次更新优先队列中的最小值,和当前的右端点, ...

  7. ajax修改密码

    <div>用户名:<input type="text" id="uid" /><span id="tt" st ...

  8. Maven的安装环境配置

    一.Maven的安装 二.Maven的配置 Settings.xml可以用来定义本地仓库.远程仓库.联网代理 Settings.xml文件可以存在两个地方: 1.多用户情况 conf目录下 2.单用户 ...

  9. INSTALL_FAILED_UPDATE_INCOMPATIBLE

    安装apk的时候,报错. 解决:把所有这个apk的相关信息删除干净,隐藏较深的是设置->应用管理->这个应用的相关信息删除干净就可以了

  10. 【转】IntentService的原理及使用

    在Android开发中,我们或许会碰到这么一种业务需求,一项任务分成几个子任务,子任务按顺序先后执行,子任务全部执行完后,这项任务才算成功.那么,利用几个子线程顺序执行是可以达到这个目的的,但是每个线 ...